Boot a Laravel Project on Docker

Faisal Islam Raju
Monstar Lab Bangladesh Engineering
6 min readAug 1, 2019

Have you ever walked on the beach watching the beautiful sunset and wondering how can I boot a Laravel project on Docker? Me neither, but here we are.

Since you are already here, you might already have some idea about Docker. In short, Docker is an open source tool which uses containers to create, build, and run applications. Containers hold all the necessary parts for the application such as dependencies and libraries. Developers don’t have to worry about on which system/platform their application is running on.

So now to the main objective. How can we boot a Laravel project in Docker.

You will need these installed in your system:

  • Docker
  • Docker Compose

You can follow these instructions to install docker in Ubuntu. Or you can select other platform and follow those instructions.

Next, let’s create a Laravel project named laravel-docker. At the time of writing this article the latest Laravel version is 5.8. I will not delve deep into how to create a Laravel project in this article, since it is more about Laravel and Docker integration.

Step 1:

We need to create the Dockerfile first. Usually the Dockerfile is kept in the root folder but I personally prefer a different folder because it makes them more manageable.

Here you can see I put the Dockerfile in .docker/apache2/Dockerfile . If we open the file we can see the code

FROM php:7.2.7-apacheARG uidRUN useradd -G www-data,root -u $uid -d /home/testuser testuserRUN mkdir -p /home/testuser/.composer && \
chown -R testuser:testuser /home/testuser
RUN apt-get update --fix-missing -qRUN apt-get install -y curl mcrypt gnupg build-essential software-properties-common wget vim zip unzipRUN docker-php-ext-install pdo pdo_mysqlRUN curl -sSL https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composerENV APACHE_DOCUMENT_ROOT=/var/www/html/publicENV APACHE_LOG_DIR /var/log/apache2ENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_LOCK_DIR /var/lock/apache2ENV APACHE_PID_FILE /var/run/apache2/apache2.pidRUN sed -ri -e ‘s!/var/www/html!${APACHE_DOCUMENT_ROOT}!g’ /etc/apache2/sites-available/*.confRUN sed -ri -e ‘s!/var/www/!${APACHE_DOCUMENT_ROOT}!g’ /etc/apache2/apache2.conf /etc/apache2/conf-available/*.confRUN a2enmod rewriteCOPY . /var/www/html/CMD [“/usr/sbin/apache2”, “-DFOREGROUND”]

Explanation of Dockerfile:

Here we are using php:7.2.7-apache image from the php Dockerhub. It has a configurable Apache web server. We will also need some other extensions which we will do in the later part.

ARG uidRUN useradd -G www-data,root -u $uid -d /home/testuser testuserRUN mkdir -p /home/testuser/.composer && \
chown -R testuser:testuser /home/testuser

We are creating a user with the name of testuser. You can create any user with any name. I am adding testuser to the user group www-data and root. If we don’t have the same user as host user, any command we execute from the CLI will create root owned files and directories.

RUN apt-get update --fix-missing -qRUN apt-get install -y curl mcrypt gnupg build-essential software-properties-common wget vim zip unzipRUN docker-php-ext-install pdo pdo_mysql

Next we execute some commands to update and install necessary packages for our web server.

RUN curl -sSL https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

Next we install Composer.

ENV APACHE_DOCUMENT_ROOT=/var/www/html/publicENV APACHE_LOG_DIR /var/log/apache2ENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_LOCK_DIR /var/lock/apache2ENV APACHE_PID_FILE /var/run/apache2/apache2.pidRUN sed -ri -e ‘s!/var/www/html!${APACHE_DOCUMENT_ROOT}!g’ /etc/apache2/sites-available/*.confRUN sed -ri -e ‘s!/var/www/!${APACHE_DOCUMENT_ROOT}!g’ /etc/apache2/apache2.conf /etc/apache2/conf-available/*.confRUN a2enmod rewrite

Here we set some basic Apache configuration. Notice that we set our root folder to var/www/html/html/public. Because that’s where our Laravel index.php file is.

COPY . /var/www/html/CMD [“/usr/sbin/apache2”, “-DFOREGROUND”]

Then we copy everything from our root folder to /var/www/html/ for Apache to serve our application and then run the next command to run Apache in the foreground.

Step 2:

We will create a new file in the project root directory named docker-compose.yml. Next we will write the following code

version: ‘3’services:  db:
image: mysql:5.7
ports:
- “3306:3306”
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: rootp
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- “81:80”
depends_on:
- db
app:
build:
context: .
dockerfile: .docker/apache2/Dockerfile
args:
uid: ${UID}
working_dir: /var/www/html
environment:
- APACHE_RUN_USER=#${UID}
- APACHE_RUN_GROUP=#${UID}
ports:
- “80:80”
volumes:
- .:/var/www/html
depends_on:
- db

Explanation:

version: 3

We state the version of docker compose. Version 3 is the latest one.

services

We will specify the containers we need and the params to build them

We will be using MySQL for our database so we create a container named db. Here we specify the params needed.

  image: mysql:5.7  ports:
- “3306:3306”
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: rootp
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}

This will pull the image for mysql 5.7 version and set default ports as 3306. In the environment section we can specify the password for the root user or can configure other users. Here we are fetching the values for MYSQL_DATABASE , MYSQL_USER, and MYSQL_PASSWORD from the env file.

phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- “81:80”
depends_on:
- db

Here we are configuring phpMyAdmin. The new configuration you see here is depends_on. This specifies which services need to be up first before this service can be activated. In this case our MySQL service needs to be up first before we initiate the phpMyAdmin service. We can put multiple service in the depends on field.

app:
build:
context: .
dockerfile: .docker/apache2/Dockerfile
args:
uid: ${UID}
working_dir: /var/www/html
environment:
- APACHE_RUN_USER=#${UID}
- APACHE_RUN_GROUP=#${UID}
ports:
- “80:80”
volumes:
- .:/var/www/html
depends_on:
- db

Here is the configuration for our app service. The build section refers to our Dockerfile and sets any argument in the args param. Our app also depends on the MySQL service. The notable configuration is volume. Volume directs docker to mount the hosts source app code into the directory we specify. In this case it’s /var/www/html . By doing this we can see the changes made by host in the container.

We will need to specify the UID in our environment file. Just add UID at the end of the .env file.

UID=1000

Now save the env, Dockerfile and docker-compose.yml. Go to your terminal and run

docker-compose up --build

Note that you will need the docker service running in your system before you execute that command.

After the build is done. Go to your browser and go to localhost and voila. Laravel is running on docker.

Laravel homepage

Now to execute commands from your recently created testuser. Run this command in your terminal

docker exec -ti -u testuser laravel-docker_app_1 bash

This will take you into containers bash as testuser. It will look similar to the picture below. It will be laravel-docker instead of laravel-dockerization.

From here you can run all the php artisan commands for the project.

So this is it for the setup of basic Laravel project on Docker. If you want the source code and immediately want to run the project then you can go to and follow the readme file:

In case you want to learn more about Docker you can read this awesome article.

Also you can read this article to understand the whole setup from a different perspective.

Check out other articles from our engineering team:

https://medium.com/monstar-lab-bangladesh-engineering

Visit our website to learn more about us:

www.monstar-lab.co.bd

--

--