Working with Laravel and Docker

If you are developing a small application that only dependent on MySQL, Apache or Nginx then MAMP is fine to get started. But what if our application dependents on Redis, Mailhog, Supervisor, Beanstalk, etc? In that case, we have 2 options Vagrant and Docker. I personally prefer Docker and of cause, this article is about setting up the Laravel with Docker.

Set up Laravel with Docker

It is very easy to setup Laravel with Docker through Laradock.

Laradock is a full PHP development environment for Docker. It includes pre-packaged Docker Images, all pre-configured to provide a wonderful PHP development environment.

In my case, I am creating a sample project with Laravel and named it to larasample. Now go to your working directory and pull the laradock from the github repository.

git clone https://github.com/Laradock/laradock.git

Now go to the laradock directory and create a new .env file through env-example file.

cp env-example .env

Here in .env file, the thing is to notice is APP_CODE_PATH_HOST, You have to make sure about the correct path before starting docker. In my case, the path of the application is correct because we have larasample/laradock application structure so the path should be the same as the .env file.

# Point to the path of your applications code on your host
APP_CODE_PATH_HOST=../

Make sure about the PHP version in .env file. We have used PHP 7.2 and we can change it to PHP 5.6, PHP 7.1, PHP 7.2 and PHP 7.3 whatever version we required.

Time to start our Laravel application in Docker Compose.

docker-compose up -d nginx mysql phpmyadmin workspace redis php-worker

Very first time when you’re running the above command it will take some time to download all the required images. Once everything downloaded check everything is running or not through the following command.

docker-compose ps
# OR 
docker ps

Both of the commands will show you the currently running containers.

Now navigate the following nginx/sites directory on laradock directory. You will find the laravel.conf.example file that is looking like this.

server {

    listen 80;
    listen [::]:80;

    # For https
    # listen 443 ssl;
    # listen [::]:443 ssl ipv6only=on;
    # ssl_certificate /etc/nginx/ssl/default.crt;
    # ssl_certificate_key /etc/nginx/ssl/default.key;

    server_name laravel.test;
    root /var/www/laravel/public;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }

    error_log /var/log/nginx/laravel_error.log;
    access_log /var/log/nginx/laravel_access.log;
}

Change it according to your working directory in the default.conf file, In our case, the setting should be like this.

server {

    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # For https
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server ipv6only=on;
    # ssl_certificate /etc/nginx/ssl/default.crt;
    # ssl_certificate_key /etc/nginx/ssl/default.key;

    server_name larasample.local;
    root /var/www/public;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }
}

Once you finished your changes in the default.conf, then you have to re-build the Nginx image with the following command.

docker-compose build nginx

Now open etc/hosts file and add the following line.

127.0.0.1  larasample.local

Connecting Laravel with MySQL

Now time to connect your laravel application with MySQL which is running by laradock. Open the .env file from your laravel project directory and change the DB_HOST=127.0.0.1 to DB_HOST=mysql

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=root
DB_PASSWORD=root

The access point for phpmyadmin interface should be 127.0.0.1:8080.

Running composer and NPM or Yarn

To running composer or npm or yarn, you have to access your workspace container. To do so run the following command to check all the running containers.

docker ps

To access the workspace container, you have to use the container name or the container id. Both will be shown when you run docker ps command. Now run the following command:

docker exec -it <container_name> bash

The above command will prompt you the working directory of your laravel project. Now you can run the composer, migration or install the required package easily. When you finished your work on your workspace terminal then simply type exit to come out of the workspace.

I hope this will help you to run your laravel application with docker. If you stuck somewhere with laradock please read the Laradock documentation to get more about the provided images and how to configure those images according to your working environment.