How to setup Laravel in Docker? [2 Methods]


Laravel

Author: Steve Alila
Reviewer: Deepak Prasad

Docker is an open-source containerization platform that simplifies the process of building, shipping, and running applications. It enables developers to package their applications into portable containers that can run on any machine with Docker installed, regardless of the underlying operating system or infrastructure.

Docker simplifies the process of setting up and deploying applications. Instead of manually installing dependencies and configuring the environment, developers can use Docker to create a container that includes everything the application needs to run. This container can then be easily deployed to any environment, such as a development, testing, or production server, without having to worry about configuration issues or compatibility problems.

For Laravel applications specifically, Docker can simplify the process of setting up the development environment and deploying the application to production. Developers can use Docker to create a container that includes the necessary components for running Laravel, such as PHP, Apache or Nginx, and the required extensions and packages. This container can then be used to develop the application locally, and later deployed to production without having to worry about compatibility issues.

It would help to know LaravelDocker, and Linux basics.- In this article, we will explore how to setup Laravel in Docker using two different methods: manually creating a Dockerfile and using Laravel Sail, a command-line interface for managing Laravel's Docker environment.

 

Pre-requisites: Install Docker

Installing Docker on Windows

Install Docker desktop and Windows Subsystem for Linux (WSL). If WSL does not install via the terminal, get it manually.

Here are the brief steps to be followed:

  1. Download the Docker Desktop installer from the Docker website.
  2. Double-click the downloaded file to launch the installer.
  3. Follow the instructions in the installer to install Docker on your machine.
  4. Once the installation is complete, open Docker Desktop from the Start menu.
  5. Docker Desktop will start a Docker engine, which enables you to run Docker containers on your machine.

 

Installing Docker on macOS

  1. Download the Docker Desktop installer from the Docker website.
  2. Double-click the downloaded file to launch the installer.
  3. Follow the instructions in the installer to install Docker on your machine.
  4. Once the installation is complete, open Docker Desktop from the Applications folder.
  5. Docker Desktop will start a Docker engine, which enables you to run Docker containers on your machine.

 

Installing Docker on Linux

Update the package index on your machine:

sudo apt-get update

Install the necessary packages to allow apt to use a repository over HTTPS:

sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common

Add Docker’s official GPG key:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add the Docker repository to your system:

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

Update the package index again:

sudo apt-get update

Install Docker:

sudo apt-get install docker-ce docker-ce-cli containerd.io

Check service status:

How to setup Laravel in Docker? [2 Methods]

Verify that Docker is installed correctly:

sudo docker run hello-world

Now that you have installed docker, let's start to setup Laravel in Docker.

 

Method-1: Setup Laravel in Docker Manually

Step-1: Create Dockerfile

Next we would need a dockerfile to build the docker image.

Use Composer base image that the Docker image should be built using the official Composer 2.x image. It sets up an intermediate build stage named "composer" that we'll use to install Laravel.

FROM composer:2 AS composer

Install Laravel using Composer t install a new Laravel project in the /app directory within the intermediate "composer" build stage.

RUN composer create-project --prefer-dist laravel/laravel /app

Use PHP-Apache base image to specify that the final Docker image should be built using the official PHP 8.1 image with Apache preinstalled.

FROM php:8.1-apache

Copy Laravel application installed in the intermediate "composer" build stage to the /var/www/html/ directory in the final Docker image.

COPY --from=composer /app /var/www/html/
COPY --from=composer /usr/bin/composer /usr/bin/composer

Install required dependencies and PHP extensions and enables the PHP PDO MySQL extension.

RUN apt-get update && \
apt-get install -y \
zip \
unzip \
git \
libpq-dev \
&& docker-php-ext-install \
pdo_mysql \
&& docker-php-ext-enable \
pdo_mysql

Set proper permissions for the storage and bootstrap/cache directories, allowing Laravel to write to these directories.

RUN chown -R www-data:www-data /var/www/html/storage \
&& chown -R www-data:www-data /var/www/html/bootstrap/cache

Enable Apache rewrite module and update document root which is required for Laravel's pretty URLs, and updates the document root in the Apache configuration to point to the public directory of the Laravel application.

RUN a2enmod rewrite && \
sed -i 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-available/000-default.conf

Optimize Laravel application by generating optimized classmaps using Composer and running the php artisan optimize command.

RUN composer dump-autoload --optimize \
&& php artisan optimize

Expose the web server port for the container will listen on port 80, the default HTTP port.

EXPOSE 80

Set the container's entrypoint to apache2-foreground, which starts the Apache web server in the foreground when the container is run.

CMD ["apache2-foreground"]

Here is the final Dockerfile:

FROM composer:2 AS composer

RUN composer create-project --prefer-dist laravel/laravel /app

FROM php:8.1-apache

COPY --from=composer /app /var/www/html/
COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
    apt-get install -y \
    zip \
    unzip \
    git \
    libpq-dev \
    && docker-php-ext-install \
    pdo_mysql \
    && docker-php-ext-enable \
    pdo_mysql

RUN chown -R www-data:www-data /var/www/html/storage \
    && chown -R www-data:www-data /var/www/html/bootstrap/cache

RUN a2enmod rewrite && \
    sed -i 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-available/000-default.conf

RUN composer dump-autoload --optimize \
    && php artisan optimize

EXPOSE 80

CMD ["apache2-foreground"]

 

Step-2: Build Docker Image

Build the Docker image using the docker build command. This command takes two arguments: the path to the directory that contains your Dockerfile (. in this case), and a name for the image (my-laravel-app in this case). Here's an example command:

# docker build -t my-laravel-app .

[+] Building 60.6s (14/14) FINISHED                                                                                                                                                                         
 => [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
 => => transferring dockerfile: 794B                                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                                      0.1s
 => => transferring context: 2B                                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/php:8.1-apache                                                                                                                                      3.2s
 => [internal] load metadata for docker.io/library/composer:2                                                                                                                                          1.9s
 => [composer 1/2] FROM docker.io/library/composer:2@sha256:2cf189b2623d0e84bb648512464ae68397fa153d0c28a7fa53ec686915e6f434                                                                           0.0s
 => [stage-1 1/7] FROM docker.io/library/php:8.1-apache@sha256:bf1c9169123ff9f025940e6c62d4b02e48451546add38d3a35f85a26fe705285                                                                       34.5s
 => => resolve docker.io/library/php:8.1-apache@sha256:bf1c9169123ff9f025940e6c62d4b02e48451546add38d3a35f85a26fe705285                                                                                0.0s
 => => sha256:bf1c9169123ff9f025940e6c62d4b02e48451546add38d3a35f85a26fe705285 1.86kB / 1.86kB                                                                                                         0.0s
 => => sha256:c8f1b0ced87a08384880bee3e3c53894e8bb5cd7196bb70816915fb6de632824 12.64kB / 12.64kB                                                                                                       0.0s
...
 => [stage-1 4/7] RUN apt-get update &&     apt-get install -y     zip     unzip     git     libpq-dev     && docker-php-ext-install     pdo_mysql     && docker-php-ext-enable     pdo_mysql         15.3s
 => [stage-1 5/7] RUN chown -R www-data:www-data /var/www/html/storage     && chown -R www-data:www-data /var/www/html/bootstrap/cache                                                                 0.6s
 => [stage-1 6/7] RUN a2enmod rewrite &&     sed -i 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-available/000-default.conf                                                             0.6s
 => [stage-1 7/7] RUN composer dump-autoload --optimize     && php artisan optimize                                                                                                                    2.4s
 => exporting to image                                                                                                                                                                                 1.7s
 => => exporting layers                                                                                                                                                                                1.7s
 => => writing image sha256:fa4912eeee761136f24fa194d8ae259447989e998cbad305d4a4722cc345ac68                                                                                                           0.0s
 => => naming to docker.io/library/my-laravel-app           

 

Step-3: Start Laravel Server

Once the Docker image is built, you can run it using the docker run command. This command takes several arguments, including the name of the image to run (my-laravel-app in this case) and any additional options or environment variables that you want to pass to the container. Here's an example command:

# docker run -d -p 8080:80 --name my-laravel-container my-laravel-app
b7d8d8072556f27b9c2a0b54f8d3cd1a370e6a13f057df7073807d48fa2c067f

# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS         PORTS                                   NAMES
b7d8d8072556   my-laravel-app   "docker-php-entrypoi…"   4 seconds ago   Up 4 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   my-laravel-container

This command will start the Docker container and map port 80 in the container to port 8080 on your local machine. You can access your Laravel application by visiting http://localhost:8080 in your web browser.

How to setup Laravel in Docker? [2 Methods]

 

Step-4: Create Docker Compose File

A Docker Compose file is a YAML file that defines services, networks, and volumes for a Docker-based application. It allows you to configure and manage multi-container applications easily. Here's how to set up a Docker Compose file for a Laravel application:

Create a docker-compose.yml file in the same directory as your Dockerfile with the following content:

version: '3.8'

services:
  app:
    build: .
    image: my-laravel-app
    container_name: my-laravel-app
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      - APP_ENV=local
      - APP_DEBUG=true

Key elements of the docker-compose.yml file:

  • version: Specifies the version of the Docker Compose file format. We are using version '3.8'.
  • services: Defines the services that make up the application. In our case, we have a single service named 'app'.
    • build: Specifies that the current directory should be used as the build context for the Docker image.
    • image: Names the Docker image that will be created, in this case 'my-laravel-app'.
    • container_name: Provides a custom name for the created container, in our example 'my-laravel-app'.
    • restart: Configures the restart policy for the container, using 'unless-stopped' to restart the container unless it is explicitly stopped.
    • ports: Maps the container's port 80 to the host's port 8080, so the Laravel application can be accessed at http://localhost:8080.
    • environment: Sets environment variables for the Laravel application, such as 'APP_ENV' and 'APP_DEBUG.

 

Step-5: Using docker compose to manage Laravel Image

Start your Docker containers using the docker-compose up command. This will start all the containers defined in your Docker-compose file.

# docker-compose up -d
Creating network "root_default" with the default driver
Creating my-laravel-app ... done

Next you can try to access the Laravel homepage

How to setup Laravel in Docker? [2 Methods]

 

Customizing the Docker environment

You can customize the Docker environment for your Laravel application by modifying the Dockerfile and/or docker-composer.yaml as per your requirement.

In my case, I had to made some customization to add DocumentRoot in the docker image, here is my updated Dockerfile

RUN composer create-project --prefer-dist laravel/laravel /app

FROM php:8.1-apache

COPY --from=composer /app /var/www/html
COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
    apt-get install -y \
    zip \
    unzip \
    git \
    libpq-dev \
    && docker-php-ext-install \
    pdo_mysql \
    && docker-php-ext-enable \
    pdo_mysql

RUN chown -R www-data:www-data /var/www/html

RUN a2enmod rewrite && \
    { \
        echo 'ServerName localhost'; \
        echo '<VirtualHost *:80>'; \
        echo '    DocumentRoot /var/www/html/public'; \
        echo '    <Directory "/var/www/html/public">'; \
        echo '        Options Indexes FollowSymLinks'; \
        echo '        AllowOverride All'; \
        echo '        Require all granted'; \
        echo '    </Directory>'; \
        echo '</VirtualHost>'; \
    } > /etc/apache2/sites-available/000-default.conf

COPY --from=composer --chown=www-data:www-data /app/public/.htaccess /var/www/html/public/.htaccess

EXPOSE 80

CMD ["apache2-foreground"]

Stop and remove any existing containers for the Laravel app, if you've already started them before:

docker-compose down

Rebuild the Docker image:

docker-compose build

Start the containers:

docker-compose up -d

The -d flag is used to run the containers in detached mode, which means they will run in the background.

You can verify it using docker ps:

# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS         PORTS                                   NAMES
86e2c02bb0b7   my-laravel-app   "docker-php-entrypoi…"   3 seconds ago   Up 2 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   my-laravel-app

 

Troubleshooting Errors

If your Laravel web application fail to load then you can use docker logs to troubleshoot any issues:

# docker logs my-laravel-app -f
[Thu Apr 20 03:05:54.499588 2023] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.56 (Debian) PHP/8.1.18 configured -- resuming normal operations
[Thu Apr 20 03:05:54.501808 2023] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
localhost:80 172.25.0.1 - - [20/Apr/2023:03:05:59 +0000] "GET / HTTP/1.1" 200 8327 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0"

Here replace my-laravel-app with your application name or you can also provide the container ID from docker ps command output. This will give you runtime updates of any activity on the webserver.

 

Method-2: Setup Laravel in Docker using Laravel Sail

Laravel Sail simplifies interacting with Laravel Docker configuration by providing simple command CLI. The package comes with docker-compose.yml file and sail script. The docker-compose.yml file defines the Docker containers, whereas the sail script provides the CLI for interacting with the containers.

Some of the Sail commands are install for publishing docker-compose.yml file to the root of the application and up for starting the containers.

Start Docker desktop then install a new Laravel application.

curl -s https://laravel.build/test_app | bash

Sample Output:

How to setup Laravel in Docker? [2 Methods]

How to setup Laravel in Docker? [2 Methods]

We create a new Laravel project called test_app. The project is created in the current directory before we execute the curl command. During the installation, sail's application containers get built on the local machine. The default services are mysql, pgsql, mariadb, redis, memcached, meilisearch, minio, selenium, and mailpit. You can choose the services to install by attaching them to the with query string. Otherwise, all the services will be pulled.

For example, the following command pulls mysql, redis, and selenium.

curl -s "https://laravel.build/test_app?with=mysql,redis,selenium" | bash

Next, cd into the project before starting Laravel Sail.

cd test_app && ./vendor/bin/sail up -d

I have started Laravel Sail in a detached mode, meaning the application runs in the background. You can view the running application by searching localhost on a browser.

The containers are up and running.

setting up laravel in docker

You can stop the containers using Laravel Sail's down command.

./vendor/bin/sail down

How to setup Laravel in Docker? [2 Methods]

Note: Although Laravel Sail gets your application up and running quickly, it is suited for a development environment. You may need to configure Docker for robust deployment and production. That entails customizing Dockerfile and docker-compose files to meet the requirements of your Laravel application.

 

Troubleshooting errors

You may get the following error:

Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3306 -> 0.0.0.0:0: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.

That means (MySQL's default) port 3306 is being used by another application.

How to setup Laravel in Docker? [2 Methods]

The error mainly arises when Xampp server runs MySQL and Apache. So, you can close the services and restart Laravel Sail.

Alternatively, you can map the mysql port to a different destination. For example, open the docker-compose.yml file and change the port

from

 ....
 mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
....

to

 ....
 mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '3307:3306'
....

Now start Laravel Sail.

# ./vendor/bin/sail up -d
[+] Running 6/6
✔ Container test_app-selenium-1 Started 2.2s 
✔ Container test_app-mysql-1 Started 2.4s 
✔ Container test_app-redis-1 Started 2.5s 
✔ Container test_app-meilisearch-1 Started 2.5s 
✔ Container test_app-mailpit-1 Started 2.1s 
✔ Container test_app-laravel.test-1 Started

 

Summary

In this article, we covered two methods to setup Laravel in Docker. The first method involved manually creating a Dockerfile, building a Docker image, starting the Laravel server, creating a Docker Compose file, and using Docker Compose to manage the Laravel image. We also discussed customizing the Docker environment and troubleshooting errors that may arise during the process.

The second method involved using Laravel Sail, a lightweight command-line interface for managing Laravel's Docker environment. We discussed how to install and configure Laravel Sail, as well as how to use it to set up a Laravel application in Docker.

Overall, both methods provide a convenient and efficient way to set up Laravel in Docker, allowing for easy management of the development environment and quick deployment of applications. By following the steps outlined in this article, developers can get up and running with Laravel in Docker in no time.

 

Steve Alila

Steve Alila

He specializes in web design, WordPress development, and data analysis, with proficiency in Python, JavaScript, and data extraction tools. Additionally, he excels in web API development, AI integration, and data presentation using Matplotlib and Plotly. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment