Creating Laravel PHP Application in Docker: Step-by-Step Guide
A challenge that every developer and development team faces is environment consistency.
At some point in your career you would most likely run into situations where code deployed to your production environment doesn’t quite work with your development environment.
Configuration and versions differences are usually the cause of these problems. Imagine developing a PHP application with PHP 7 on your local machine with all the required modules enabled and deploying it to a production environment only to discover the modules your application requires to run are absent. To solve this
problem, we started using VM(virtual machines) to maintain environment consistency; however, we soon discovered that VMs are not very efficient or portable. They are typically time consuming and require a lot of system resources to function properly.
This is where Docker comes in.
Docker containers wrap a piece of software in a complete filesystem that
contains everything needed to run: code, runtime, system tools, system libraries
— anything that can be installed on a server. This guarantees that the software
will always run the same, regardless of its environment.
With Docker, you can build and run lightweight containers for any services needed. Need to upgrade to a newer version of PHP? No problem, Docker allows you to destroy your entire environment, reconfigure it, and run it againquickly.
Laravel (one of the best things that happened to PHP) integrates a lot of technologies (MySQL, Redis, MongoDB, Memcached, etc) in order to provide a wide array of functionalities. It can be quite a challenge to get a good configuration initially — the goal of this post is to provide some understanding of building Laravel apps with Docker.
tldr; You can check out the code for this at
- Laravel setup
- Docker setup
- Local environment setup
- Adding a database
We’ll be working with Laravel 5.3 in this post and we’ll be installing it with
The next step is to verify your installation
$ cd docker-laravel $ php artisan serve
Docker runs on Mac, Windows, and Linux. Select your platform to install Docker on your machine. Be sure to install Docker as well as
Docker Compose, which we will use in this post.
After installing it, you should be able to verify the installation with these commands:
(I already have some containers running)
If you get an error running the docker ps command, you would need to open Docker and start it manually.
Local environment setup
The next step is to get the local environment setup right. If you've set up a PHP environment before, you are probably already familiar with running PHP alongside a web server like Nginx or Apache. With Docker, we can create containers to house
specific parts of the infrastructure of our local environment. We’ll have a container that runs nginx to handle web request, another container to handle application requests with PHP-FPM, and a few others to handle the application’s database and caching needs. Each container will have a responsibility and all containers
will be linked together to communicate.
Overview of environment
Next up, we’ll use Docker Compose
to put all the pieces together in our environment. In the root of the project, create a file named
- We have defined two services AKA containers; web and app
- The web and app containers are set to use the project root as the context, from
which the docker-compose tool builds out environment. The files also specify
the names of
web.docker), which will instruct Docker on how to build our containers.
- The next thing you’ll set is the volumes directive. This allows us to mount
our project directory as volume on the container at the specified path, in this
- The web container exposes port 8080 on our machine and maps it to port
80 on the container, allowing us access to the app.
- The links directive allows us to link one container to another, allowing
us to reference the **app **container as a host from within the web
The docker documentation has more information about configuration
directives and is available for Docker Compose; you can check it out
Let's create the Dockerfiles for our containers. Dockerfiles are essential files
containing instructions on how to build a container image. These instructions
are similar to the typical steps taken to provide a server for a task — web
server, database server, PHP app server, etc. Dockerfiles allow us to leverage
already created base images, which minimize configuration.
In line 1, we specify the base image for our app container to be PHP-FPM using
FROM, with this convention you can easily switch to a different versions of
the base image. Our base image is pulled from the Docker
Hub, which houses a lot of other base images.
In line 2, we run some commands to make sure our container is up to date and fetch some dependencies for our application.
app.docker file, we specify a base image and perform some
configuration. In line 3, we add an Nginx configuration file to the web container.
vhost.conf file contains standard Nginx configuration that will handle
requests and proxy traffic to our app container on port 9000. Remember from
earlier, we named our container app in the Docker Compose file and linked it to the web container; here, we can just reference that container by its name and Docker will route traffic to that app container.
Next up, run this command from the root of the project
$ docker-compose up -d
This command tells Docker to start the containers in the background. The first
time you run the command, it might take some time to download the two base
images, after that it will be much faster. You can now visit the app.
*Note: Docker may not be using localhost (like on Windows sometimes). Run and
get the IP address to use instead.
Now our laravel app, powered by docker containers, is up and running.
Adding a database
So we’ve got our Laravel app up and running, the next step is to add another container to handle the application’s database needs. First, let’s stop our containers.
$ docker-composer kill #stops all running containers
Next, we’ll update the
docker-compose.yml file and add a MySQL base image for our
We made a few changes here:
- Added link on the container to the container.
- Added environment variables to the app container, which will allow us to configure our local machine to connect using the config values set in the laravel file. This allows us to run artisan locally without messing with the
connection details that are used inside the container.
- Created the container using the mysql base
image and set environment values to configure some defaults for the image.
- Expose port on our machine and forward it to the container. This allows us to run artisan locally.
Now, in our
.env file for Laravel, we can configure the connection details.
Now you can start up your updated environment with
$ docker-compose up -d
You now have database container to store data. You can now create the laravel migrations table on your database and create laravel database migrations as usual.
You can check if the mysql container is running with
$ docker ps
In this post, we successfully dockerized our local laravel environment. Now we can easily
update the Docker Compose fill and add new containers for more services like Redis, MongoDb, etc.