Explain in detail the docker file of Laravel 11

There are several ways to dockerize your Laravel project some of them are simple and others are complicated so we will dive into most of the ways to dockerize your project using :


1- docker file.
2- Laradock.
3- Laravel sail.

Requirements


1- install docker on your machine and here is the link that will guide you to install docker for different platforms.
https://docs.docker.com/get-docker/
2- some knowledge of Linux commands but not necessary.
3- Laravel package installed and here is the link that will guide you how to install it.
https://laravel.com/docs/11.x/installation

First, let me show you how to create a docker file for the Laravel package :


Step 1: configure the .env file and create a docker file then configure Nginx

  • DB_CONNECTION. (like MySQL, PostgreSQL, etc.)
  • listed here are used for the deployment.
  • DB_HOST. When deploying a Laravel app in Docker, this field should contain the name of the database service.
  • DB_PORT. The database port, with 3306 as the default value.
  • DB_DATABASE. The name of the database.
  • DB_USERNAME and DB_PASSWORD. The database credentials.
    Step 2: Create Dockerfile
    After we configure the .env file in Laravel we can proceed to create a Dockerfile I will show you the code then I will explain it step by step
  1. create a file named Dockerfile in the main directory of Laravel with the following code afterward I will explain that code in detail
FROM php:8.2-fpm 
ARG user 
ARG uid 
RUN apt update && apt install -y git curl libpng-dev libonig-dev libxml2-dev 
RUN apt clean && rm -rf /var/lib/apt/lists/* 
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd 
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer 
RUN useradd -G www-data,root -u $uid -d /home/$user $user 
RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user 
WORKDIR /var/www 
USER $user
FROM php:8.2-fpm

the first line says please pull the image called PHP with the version 8.2-fpm so you can change the version of the PHP which is suitable for your Laravel package version here I used this version that is suitable for Laravel 11.

ARG user 
ARG uid 

those two lines are the name of the variable you define, and you can optionally assign a default value. Note that you can define multiple ARG instructions in your Dockerfile. Each ARG allows you to pass different variables during the build process so we define two variables one for *user* and the second for uid which is the user identifier in the Linux system.

RUN apt update && apt install -y git curl libpng-dev libonig-dev libxml2-dev

These commands are very common in Linux systems which tell the system to make updates to the packages inside it and install Git, Curl … etc.

RUN apt clean && rm -rf /var/lib/apt/lists/* 

After installation, we do different things. 

rm -rf /var/lib/apt/lists/* removes package lists, loaded by apt update

apt clean removes cached packages, loaded by apt install or apt upgrade.

RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd 

Install necessary extensions for PHP.

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

we will just copy the composer binary into the PHP docker image.

RUN useradd -G www-data,root -u $uid -d /home/$user $user 

Here we create a user with groups www-data, root, and uid that we will define in another step and default home directory /home/$user and the name of the user is variable $user

RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user 

We create a .composer directory inside of the home directory and change the owner to the user owner variable.

  1. Configure Nginx by creating a directory for the Nginx configuration in the main app directory with hierarch docker-compose/nginx/[app-name].conf then Copy and paste the following code into the file.
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;
    }
}

Step 2: Create docker-compose.yml create a Docker Compose [YAML file] that defines the service network and three separate containerized services that make up the deployment. Follow the steps below to set up the file:

  1. Create the Docker Compose file in the main app directory
docker-compose.yml
  1. Paste the following code and replace the values in square brackets with your actual values:
version: "4.3"
services:
  app:
    build:
      args:
        user: [current-user]
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: [image-name]
    container_name: [container-name]
    restart: unless-stopped
    working_dir: /var/www/
    volumes:
      - ./:/var/www
    networks:
      - [network-name]
  db:
    image: mysql:8.0
    container_name: [db-container-name]
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker-compose/mysql:/docker-entrypoint-initdb.d
    networks:
      - [network-name]
  nginx:
    image: nginx:alpine
    container_name: [nginx-container-name]
    restart: unless-stopped
    ports:
      - 8000:80
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d/
    networks:
      - [network-name]
networks:
  [network-name]:
    driver: bridge

The file has four sections:

  • services.app. The app section tells Docker Compose to use the main app directory as the context and the Dockerfile as instructions to create a [Docker image]
  • services.db. This section provides information about the DBMS image and assigns the values provided in the app’s .env file to the database’s [environment variables]
  • services.nginx. The web server section maps the internal Docker port 80 to the external port 8000. It also connects the Nginx configuration directory created in a previous step with the Nginx’s conf.d directory inside the service container.
  • networks. All the previous sections specify the network that enables them to connect. The network section defines the driver for that network.

Step 3: Build Application

docker-compose build app

Wait for the procedure to finish. If there are no errors, Docker Compose outputs the success messages.

Step 4: Run the application

docker-compose up -d

2- Laradock.

Step 1: Clone Laradock on your project root directory:

git submodule add https://github.com/Laradock/laradock.git

Note: If you are not using Git yet for your project, you can use git clone instead of git submodule.

Step 2: Make sure your folder structure should look like this:

* project-a
*   laradock-a
* project-b
*   laradock-b

Step 3: Enter the laradock folder and copy .env.example to .env

cp .env.example .env

You can edit the .env file to choose which software’s you want to be installed in your environment. You can always refer to the docker-compose.yml file to see how those variables are being used.

Step 4: Build the environment and run it using docker-compose

docker-compose up -d nginx php-fpm mysql

Step 5: Enter the Workspace container, to execute commands like (Artisan, Composer, PHPUnit, Gulp, …)

docker-compose exec workspace bash

Alternatively, for Windows PowerShell users: execute the following command to enter any running container:

docker exec -it {workspace-container-id} bash

Note: You can add --user=laradock to have files created as your host’s user. Example:

docker-compose exec --user=laradock workspace bash

You can change the PUID (User id) and PGID (group id) variables from the .env file)

Step 6: Update your project configuration to use the database host

Open your PHP project’s .env file or whichever configuration file you are reading from, and set the database host DB_HOST to mysql:

DB_HOST=mysql

You need to use the Laradock’s default DB credentials which can be found in the .env file (ex: MYSQL_USER=). Or you can change them and rebuild the container.

Step 7: Open your browser and visit your localhost address.

Make sure you add use the right port number as provided by your running server.

http://localhost

3- Laravel sail.


It’s the easy peasy way to dockerize your Laravel project let’s show you how to do that:

The first thing is install the sail package for laravel
composer require laravel/sail --dev

After Sail has been installed, you may run the sail:install Artisan command. This command will publish Sail’s docker-compose.yml file to the root of your application and modify your .env file with the required environment variables in order to connect to the Docker services:

php artisan sail:install

Finally, you may start Sail

./vendor/bin/sail up

[Starting and Stopping Sail]

Laravel Sail’s docker-compose.yml file defines a variety of Docker containers that work together to help you build Laravel applications. Each of these containers is an entry within the services configuration of your docker-compose.yml file. The laravel.test container is the primary application container that will be serving your application.

Before starting Sail, you should ensure that no other web servers or databases are running on your local computer. To start all of the Docker containers defined in your application’s docker-compose.yml file, you should execute the up command:

sail up

To start all of the Docker containers in the background, you may start Sail in “detached” mode:

sail up -d

Once the application’s containers have been started, you may access the project in your web browser at: [http://localhost].

To stop all of the containers, you may simply press Control + C to stop the container’s execution. Or, if the containers are running in the background, you may use the stop command:

sail stop

Conclusion

Congrats on completing the Laravel Dockerization tutorial! By now, you should have a functional Laravel development environment running within Docker containers.

Here’s a recap of the benefits you’ve unlocked:

  • Consistency: Your development environment is now independent of the host machine’s configuration. Everyone on your team can work with the same setup.
  • Portability: Just share the Dockerfile and docker-compose.yml file, and anyone can set up the environment on their machine.
  • Isolation: Your Laravel application runs in its own container, preventing conflicts with other projects or system dependencies.
  • Scalability: Adding more resources (like additional database containers) is a breeze with Docker.

This is just the beginning! Docker offers a powerful toolset for managing and deploying applications. Feel free to explore further configurations and customizations to tailor Docker to your specific Laravel development workflow.