“How do I get new team members contributing code to the project in a matter of minutes/hours not days?” is a common question heard in development teams. There are some ways to do, in my opinion docker is one of the best.
Docker enables using same software stack in development, staging and production. You don’t need to worry about the version of PHP, MYSQL or any other dependency with Docker. This post will be about Laravel and MariaDB (MySQL) with Docker for local development. It will also feature use of docker-compose. We will use PHP 5.6 and MariaDB 10.1 with Laravel 5.1.
- You are aware about docker and is basic usage. If you are new to docker check an introduction screen-cast) or read this Docker for PHP Developers post
- You know about docker volumes and linking containers with docker-compose.
- You are running Laravel 5.x on your local machine with some PHP and MySQL setup. The setup can be local LEMP stack or XAMPP or something similar.
- You have docker and docker compose installed on your machine
- You have stopped your Apache/Nginx service and MYSQL service. It will free port 80 and 3306. If you are using vagrant and homestead then you can run Laravel without starting it.
Software Versions used
I am running this example on Ubuntu 14.04.2 LTS.
Why use docker?
The reasons to use docker are simiar to vagrant. There are some more compelling reasons to use docker and docker compose, some of them are:
Quick setup of development environment
The developer/software engineer does not need to know which version of PHP or MySQL is in use. All s/he needs to do is
docker-compose up and wait for the images to download (around 230 MB). After that add a entry to the /etc/hostsfile like
echo 127.0.0.1 project-name.dev >> /etc/hosts. Then the project runs at
http://project-name.dev on the browser.
No need to install software on local machine
With docker containers applications are self sufficient. There is no need to upgrade to the latest version of PHP or MySQL. The right version is already packaged inside the dockerfile and also in the container. There is no problem of one developer running PHP 5.5 and another one running PHP 5.6. All developers run the same container. You can install PHP to run composer and other scripts.
Same software stack in all environments
Same docker container can be deployed to staging or production environments. The same software stack with correct software versions is used across environments. For example the problem of one developer using MySQL 5.6 and staging running MySQL 5.5 ends.
A NGINX proxy can be used to make the virtual hosts dynamic. This post is about keeping things simple.
Steps to running Laravel 5.x with MariaDB (MySQL) with docker
For this example I will use docker images with Alpine Linux base images. Alpine image is just 5 MB which makes it the best candidate for docker base images. We will use PHP version 5.6 and MariaDB version 10.1. MariaDB is a drop in replacement of MySQL and for Alpine only MariaDb is available. The example git repo for this blog post is available on github.
Install Laravel 5.1 on local machine
Run the following command:
I installed it on
Add larael-docker.dev to /etc/hosts
While it is downloading Laravel add
127.0.0.1 larave-docker.dev to your
/etc/hosts file. It can be
done quickly with the command below:
Setup docker images with docker-compose
We will use dydx/alpine-nginx-php-mariadb and modify it to suit our needs. It is a docker replacement for homestead. Both docker images are based on Alpine Linux which makes it small. Create the following
docker-compose.yml file on root of the project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- We are using dydx/alpine-nginx-phpfpm image named as front, it has PHP Nginx 1.8 and PHP-FPM.
- It uses supervisor to keep nginx and PHP-FPM running.
- We copy the all the files in current folder inside docker at
/var/wwwto execute it.
- Other volumes are there to override the sites-enabled with virtual host and supervisor config to fix an error.
- The second definition is MySQL for which the data is saved in ./docker/db/data folder.
- The front container links the MySQL (MariaDB) container with the name
Create needed folders
In project root create the following folders:
1 2 3 4
All MYSQL/MariaDB data that would generally be stored in
/var/lib/mysql will be linked as volume from
This is done as docker containers don’t have data persistence. This will keep the MySQL data persisted on the host machine which will be reused when the MySQL/MariaDB container is restarted. The folder structure should
be like below:
Create default sites-enabled
Create a file named
./docker/nginx/sites-enabled like below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
Run Docker compose up
Now give you are in the project root, you can run
docker-compose up to build and run the containers.
Wait for the containers to download. You can do more customization if you create your own image and do a
docker-compose build to build the images.
After you run docker-compose up you will see output like below:
The containers are up still as the cache and logs are not writable it will hit a 500 Internal server error. To fix this use the following command to relax the file permissions inside the container in a new console tab.
or it can be done locally too with the following command:
If you want to run your artisan commands you can run them inside the front container. Hit the command below:
You will get the shell of the front container then do
cd /var/www and
php artisan all your artisan commands are there.
You should be able to load Laravel in the browser now navigating to
http://laravel-docker.dev. Here you can see the Laravel 5 default page loading.
You can check if MySQL/MariaDB is running by logging into MySQL locally with:
This will connect to you local port 3306 and you can see that mysql is working. You can even use tools like MySQL workbench to verify that MySQL is working fine.
From the container when you connect to MySQL the
DB_HOST is not localhost anymore it should be
mysql (as set in docker-compose.yml file) and you are all set to use MySQL. As an example have a look at the db part of .env file I used:
1 2 3 4
The easiest way to verify if Laravel is talking to MySQL/MariaDb correctly is just run the following command:
1 2 3 4 5 6 7
Then you will see some messages like below:
1 2 3
Now run the following queries on MySQL/MariaDb via the cli client or some other client like MySQL Workbench.
You will get an output like below:
Stop docker containers
You have seen that docker is running from the containers. To stop your containers you should run:
on the project root and it will stop the containers like below:
You can carry on using the docker containers to replace your local Apache/Ngnix and MySQL. You can develop your Laravel applicaiton with ease using docker and docker compose.
You can use this analogy that containers are cattle and virtual machines (VMs) are pets.
Creating, deleting and reconstructing the containers should be easy, fast and seamless than VMs. If you want to speed up your development flow and help other team members contribute faster to the project opt for docker and docker-comopse. Happy Dockerizing and coding Laravel + PHP!