Laravel and Docker

☞ Azraar Azward
Oct 1, 2018 · 5 min read

What is Docker?

Most developers use WAMP/LAMP/MAMP/XAMPP to set up the local environment to run PHP projects.

but this environment can be a trouble for example, when you need to have multiple versions of PHP/MYSQL or one project on Nginx and another on Apache.

As a solution for this problem, we started using VirtualBox to keep the host computer clean, and the projects separated. To make this setup
portable and easy to share, Vagrant came into play. Using Vagrant we can share our project with other team members, so everyone in the Team can reproduce the same configurable environment. But the issue is the no of resources vagrant is going to use and when we have more projects with different versions of technologies, we will end up having so many virtual machines with the OS that would eat up the disk space with tens of GBs and RAM.

Docker is a container virtualization software. It isolates individual services in a container and runs them independently on the operating system. Virtualization with Docker is very lightweight and saves resources on the host system.

Installing Docker

You can download and install Docker Community Edition from https://store.docker.com/search?type=edition&offering=community

I’m working with the Docker Version 18.06.1-ce, build e68fc7a and the Docker Compose Version 1.22.0, build f46880f

Lets create a directory to config Docker and install laravel. I just named it as docker-project

mkdir docker-project
cd docker-project

Installing laravel

curl -L https://github.com/laravel/laravel/archive/master.zip | tar xz 
mv laravel-master laravel

To keep it clean, i separate the docker configurations from the actual code. Lets create a directory called docker for that purpose.

mkdir docker
cd docker
touch docker-compose.yml
vim docker-compose.yml

Now we need put up the configurations in docker-compose.yml

first line starts with the version. version: ‘3’ and then follow the services. In our case the app is for the Laravel application, web for the web server nginx and database for the MySQL database.

App service

app:
build:
context: ./
dockerfile: app.dockerfile
working_dir: /var/www
volumes:
- ./../laravel:/var/www
environment:
- "DB_PORT=3306"
- "DB_HOST=database"

In the app service, the actual Laravel application is configured as a container.
app.dockerfile we will create shortly to include what packages needs to be pre installed inside this container.
We use volumes to map from the local directory ../laravel to the Docker container path /var/www .
In addition, we set the env variables like the database information.

Web service

web:
build:
context: ./
dockerfile: web.dockerfile
working_dir: /var/www
volumes:
- ./../laravel:/var/www
ports:
- 8080:80

The web service contains the web server nginx. This is configured via the web.dockerfile. As you can see we map Port 8080 to port 80 so our application can accessed via 127.0.0.1:8080.

Database service

database:
image: mysql:5.6
volumes:
- dbdata:/var/lib/mysql
environment:
- "MYSQL_DATABASE=homestead"
- "MYSQL_USER=homestead"
- "MYSQL_PASSWORD=secret"
- "MYSQL_ROOT_PASSWORD=secret"
ports:
- "33061:3306"

Image is to say what docker image to use and in our case we are using MySQL 5.7. you can browse docker hub at https://hub.docker.com/_/mysql/ to see more available MySQL images.

Here is the entire docker-compose.yml:

version: '3'
services:
app:
build:
context: ./
dockerfile: app.dockerfile
working_dir: /var/www
volumes:
- ./../laravel:/var/www
environment:
- "DB_PORT=3306"
- "DB_HOST=database"
web:
build:
context: ./
dockerfile: web.dockerfile
working_dir: /var/www
volumes:
- ./../laravel:/var/www
ports:
- 8080:80
database:
image: mysql:5.6
volumes:
- dbdata:/var/lib/mysql
environment:
- "MYSQL_DATABASE=homestead"
- "MYSQL_USER=homestead"
- "MYSQL_PASSWORD=secret"
- "MYSQL_ROOT_PASSWORD=secret"
ports:
- "33061:3306"
volumes:
dbdata:

Configuring the app service

We install PHP, the MySQL client, Imagick, Composer, Git and Zip and any other packages required for your application.

touch app.dockerfile
vim app.dockerfile

Copy paste the below code and save it.

FROM php:7.1.3-fpmRUN apt-get update
RUN apt-get install -y libmcrypt-dev
RUN apt-get install -y mysql-client
RUN pecl install imagick
RUN docker-php-ext-enable imagick
RUN docker-php-ext-install mcrypt pdo_mysql
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
RUN apt-get install -y git
RUN apt-get update && apt-get install -y zlib1g-dev
RUN docker-php-ext-install zip

Configuring the web service

We are using nginx as a web server. Lets see how we can configure this as a Docker container.

Create the dockerfile and copy paste the code below and save it.

touch web.dockerfile
vim web.dockerfile

web.dockerfile should like as below.

FROM nginx:1.14ADD vhost.conf /etc/nginx/conf.d/default.conf

We are using nginx 1.14 and our vhost.conf is used as default.conf for nginx.

To create the vhost.conf file do the same.

server {
listen 80;
index index.php index.html;
root /var/www/public;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

Thats all, Now we have configured everything, we can start our docker containers by running

docker-compose up -d

First time it takes a while and you will see docker downloads packages from the internet to set up the containers.

Now lets try to run the laravel app by executing the following commands in the shell.

docker-compose exec app mv .env.example .env
docker-compose exec app composer update
docker-compose exec app php artisan key:generate

We can now call http://localhost:8080 in the browser see our Laravel installation.

All laravel artisan commands can be run on the shell like we saw previously.

Example:

docker-compose exec app php artisan make:auth
docker-compose exec app php artisan migrate
docker-compose exec app php artisan tinker

Finally, if you don’t prefer writing docker commands and need a GUI like WAMP/MAMP/LAMP/XAMPP you can try the below GUI based tools to setup docker.

https://kitematic.com/
https://portainer.io/

If you need a fully loaded docker setup for your local environment. Try https://laradock.io/

☞ Azraar Azward

Written by

An eager Software Engineer always loving to reach the impossible.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade