Dockerizing Laravel. How to Create a Laravel Development Environment Using Docker

Máximo Martinez Soria

Feb 23, 2022 | 4 min to read |

Devops

Now that you understand how Docker works and some of the tools it provides, it’s time to put everything into practice. To do that, we’re going to create a Laravel project and run it using Docker.

Project analysis

Whenever we start a project, we need to think about which tools we’ll initially need in order for everything to work correctly.

In our case, we’ll need:

  • An operating system. Linux.
  • A programming language. Laravel is written in PHP.
  • A web server. Nginx.
  • A database engine. MySQL.
  • Node to use SCSS or SASS and Vue.

Project installation

Enough analysis. Let’s start with the fun part.

Create a Laravel project

First things first, let’s install Laravel. The most common way is using composer, but in this post we aim to avoid even having PHP installed locally to run a Laravel project. That’s the magic of Docker.

For that reason, we’ll install Laravel using the following command:

curl -s "https://laravel.build/example-app" | bash

This will create an example-app directory with the Laravel project inside. Feel free to rename it as you wish.

Recent versions of Laravel ship with a docker-compose.yml file. This file defines the services needed to run the project using Sail, a tool created by the Laravel team as an abstraction layer on top of Docker. In our case, we want to learn Docker itself, so we’ll delete that file.

rm docker-compose.yml

Server

The first step is to look up the nginx image we’ll use on Docker Hub.

Next, we’ll create a docker-compose.yml file. As explained in the Introduction to Docker post, we don’t want to run a command per service. That’s why we use this great tool called docker compose.

version: "3.8"

services:
  server:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - 81:80
      - 444:443
    networks:
      - app-network
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/

networks:
  app-network:
    driver: bridge

The first thing we define in docker-compose.yml is the docker compose version. This must always be explicit. In our case, we’ll use version 3.8, which is the latest at the time of writing.

Once that’s set, we can start defining what’s needed to run nginx. We do this by defining a service inside services.

We’ll name this service server and tell it to create a container from the nginx:alpine image. Inside the volumes section, we bind the current directory to /var/www inside the container so it can access our code. We also bind the local ./nginx/conf.d/ directory to /etc/nginx/conf.d/ inside the container.

We also need this container to communicate with others, so we connect it to the app-network, which we define below.

Port 80 is exposed on the container, not on our computer. That means accessing localhost:80 directly won’t work.

To access it from the browser, we bind a local port to the container’s port 80 using the syntax local-port:container-port.

In my case, I used port 81 locally. Now we can run docker-compose up and access the container via localhost:81.

To finish configuring the server, we’ll add the nginx configuration file at ./nginx/conf.d/app.conf with the following content:

server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    location ~ \.php$ {
        try_files $uri =404;
        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;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

Conclusion

Done. We now have Laravel running on Docker.

To ensure everyone on the team has the same environment, all we need to do is commit the files we created to the repository.

Author

Máximo Martinez Soria