Containerize your Laravel Application with Docker Compose

In this article, we will learn how to set up the Laravel development environment with Docker. We are going to use the Docker Compose to set up the development environment. Let’s start the steps without delay.

This may also help: Laravel, Nginx and MySQL configuration with Docker Compose

Video Tutorial

Step 1 – Download Laravel to your local machine

The first step to download the Laravel to your local machine and you can achieve this by downloading the Laravel from it’s official GitHub repository. If you have git installed then you can use the git clone command or you can directly download it.

git clone https://github.com/laravel/laravel.git laravelapp
Laravel Docker File Structure

Step 2 – Create Docker Compose File

Let’s create the docker-compose.yml file under our working directory i.e. laravelapp. We required only two services for the basic laravel development setup. So, we are going to set up the PHP and Apache through app service and the db service for the database setup for our Laravel application.

You can name anything instead of [app] or [db] to the services. But it’s a good practice to give the relevant name.

version: '3.7'
services: 
  app:
  db:

Step 2.1 – Create Database Service

version: '3.7'
services:  
  db:
    image: mysql:5.7
    restart: always
    ports: 
      - "3306:3306"
    environment:
      MYSQL_DATABASE: 'laraapp_db'
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      MYSQL_ROOT_PASSWORD: ""
    volumes:
      - ./db:/var/lib/mysql

Let’s understand the above steps one by one. Let’s start with the image key. We have to provide the name of the official public image that you can find at hub.docker.com, as you see that we have defined the image name i.e. mysql:5.7 where 5.7 is the version of MySQL image.

The next key is restart:always the reason for this markup is because a container does not restart if it fails under any circumstance.

As the name suggests, the ports key is used to define the local port over the image’s own port. In our case, we have mapped the db directory with the host’s /var/lib/mysql directory.

The next key is an environment, which is used to assign a value to the specific image. In our case, we are using the mysql:5.7 image and this image have various a variety of environment variables that you can find through the official image’s documentation page.

The next one is the volumes key. The volumes key mounts the project directory (current directory) on the host.

Step 2.2 – Create Separate Service for PHP and Apache Server

version: '3.7'
services:    
  app:
    build:
      context: .
      dockerfile: .docker/Dockerfile
    image: 'laravelapp'
    ports:
      - 8080:80
    volumes:
      - ./:/var/www/html

As you see, the app service set up is a bit different from the db service. And the reason because we don’t have any official image dedicated to Laravel. We have to build our own setup for the Laravel with PHP and Apache image. The build key is used to set and use its own configuration with the help of Dockerfile. If your Dockerfile is on the root of the project directory then you don’t need to use the context and the dockerfile keys and you can use instead build: . that’s it.

But in our case, we have separated the custom docker configuration in a .docker directory. And later defined the Dockerfile path through the dockerfile key in our app service.

Step 2.3 – Setup Laravel Development Environment through Dockerfile

The first step is to create a .docker directory in your project’s root directory. Now create a file with the name Dockerfile under the .docker directory. We required PHP, Apache, and Composer for the Laravel application. So, we are going to use the PHP docker image with apache and we will install the rest of the requirements. Now open the Dockerfile and paste the given codes.

FROM php:7.4.1-apache

USER root

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y \
        libpng-dev \
        zlib1g-dev \
        libxml2-dev \
        libzip-dev \
        libonig-dev \
        zip \
        curl \
        unzip \
    && docker-php-ext-configure gd \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install mysqli \
    && docker-php-ext-install zip \
    && docker-php-source delete

Start with the FROM that creates a layer for the official php:7.4.1-apache Docker image. Next, define the USER and the WORKDIR for the host machine as the name suggests. Next, Install the required packages and the PHP extensions for the Laravel application. We are leaving the Dockerfile as it as for a moment and moving to another step that required to set up the DocumentRoot for the apache machine.

Step 2.4 – Virtual Host Environment Settings for Apache

Let’s create a virtual host configuration file and add that to the host machine. Let’s create a file vhost.conf under the .docker directory.

Keep in mind that the DocumentRoot should be public for the Laravel application.

<VirtualHost *:80>
    DocumentRoot /var/www/html/public

    <Directory "/var/www/html">
        AllowOverride all
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

As we already mapped in our app service through the docker-composer.yml file our Laravel application exists on the /var/www/html/ host directory. And we assigned the DocumentRoot as /var/www/html/public for our application.

Now move to Dockerfile and use the COPY directive to copy our local vhost configuration to apache configuration.

COPY .docker/vhost.conf /etc/apache2/sites-available/000-default.conf

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

RUN chown -R www-data:www-data /var/www/html \
    && a2enmod rewrite

Then next step we followed is to install the composer to our machine. Next set up the ownership to the working directory and enable the apache’s rewrite module.

The complete Dockerfile should look like to the given codes.

FROM php:7.4.1-apache

USER root

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y \
        libpng-dev \
        zlib1g-dev \
        libxml2-dev \
        libzip-dev \
        libonig-dev \
        zip \
        curl \
        unzip \
    && docker-php-ext-configure gd \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install mysqli \
    && docker-php-ext-install zip \
    && docker-php-source delete

COPY .docker/vhost.conf /etc/apache2/sites-available/000-default.conf

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

RUN chown -R www-data:www-data /var/www/html \
    && a2enmod rewrite

And the docker-compose.yml should look like the below example.

version: '3.7'
services: 
  app:
    build:
      context: .
      dockerfile: .docker/Dockerfile
    image: 'laravelapp'
    ports:
      - 8080:80
    volumes:
      - ./:/var/www/html
  db:
    image: mysql:5.7
    restart: always
    ports: 
      - "3306:3306"
    environment:
      MYSQL_DATABASE: 'laraapp_db'
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      MYSQL_ROOT_PASSWORD: ""
    volumes:
      - ./db:/var/lib/mysql

Step 3 – Start Laravel Application with Docker Compose

Now its time to start our Laravel application. Go to the terminal and navigate the laravelapp ( as per this article ) directory and run the given command.

docker-compose up -d

The given command starts the docker on detachable mode as the -d option. It will take some time at very first time because the docker first checks for the existing images and it will download the images in case not found in local machine.

Next check the running Container ID to login to the host machine. And you need to run the docker ps command to check all the running containers.

Docker Container ID

Now time to access the hosting machine through the container id i.e. 83ad4ef2b5dc as per the screenshot and it should be different if you check in your local machine.

docker exec -it 83ad4ef2b5dc bash

You should see the output similar to the below image.

Now you can install the composer packages by using the composer install command.

Step 4 – Laravel Database Connection in Docker

Now we have to connect the database to our laravel application. Which is pretty simple though the .env file.

....

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laraapp_db
DB_USERNAME=root
DB_PASSWORD=

....

As we know that database is running through a separate service i.e. db, So in this case, the DB_HOST should be db instead of localhost.

I hope you guys enjoyed this article and if you like this article, then please follow us for more interested and helpful tutorials. You can follow us on Facebook and Twitter.