This is LARA Nepal. X

Run Laravel 11 With Docker, Supervisor, And Postgresql For A Scalable Development Setup

Published on December 21, 2024 by

Run Laravel 11 with Docker, Supervisor, and PostgreSQL for a Scalable Development Setup

Running a Laravel 11 Project in Docker with Supervisor and PostgreSQL

Introduction

Docker simplifies running Laravel projects by offering isolated, reproducible environments. This guide walks you through setting up a Laravel 11 project in Docker using Supervisor for managing background processes and PostgreSQL as the database.

Prerequisites

Before starting, ensure you have the following:

  1. Docker and Docker Compose installed on your system.
  2. Laravel 11 installed in your project directory.

Folder Structure

Your project directory should include a .docker folder containing Docker configuration files:

project-root/
├── .docker/
│ ├── php/
│ │ ├── Dockerfile
│ │ └── supervisord.conf
│ ├── nginx/
│ │ └── default.conf
│ └── php-supervisor/
│ ├── log/
│ └── Dockerfile
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
├── .env
├── docker-compose.yml

Step 1: Setting Up Docker Compose

Create a docker-compose.yml file in your project root with the following content:

version: '3.8'
 
services:
app:
build:
context: .docker
dockerfile: php/Dockerfile
container_name: laravel_11_app # Change this to your project name
ports:
- "9001:9000"
volumes:
- .:/var/www/html
networks: # Connect to the laravel_network
- laravel_network
restart: unless-stopped
depends_on: # Wait for the database to start
- db
 
nginx:
image: nginx:alpine
container_name: laravel_11_nginx
ports:
- "8080:80"
volumes:
- .:/var/www/html
- ./.docker/nginx/default.conf:/etc/nginx/conf.d/default.conf # Nginx configuration
networks:
- laravel_network
depends_on:
- app
 
db:
image: postgres:15
ports:
- "5433:5432"
restart: always
environment:
POSTGRES_DB: laravel # Change this to your database name
POSTGRES_USER: root # Change this to your database user
POSTGRES_PASSWORD: root # Change this to your database password
networks:
- laravel_network
 
supervisor:
build:
context: .docker
dockerfile: php-supervisor/Dockerfile
container_name: laravel_11_supervisor
volumes:
- .:/var/www/html
networks:
- laravel_network
depends_on:
- app
 
volumes: # Persist the database data
db_data:
 
networks: # Create a network for the services to communicate
laravel_network:
driver: bridge

Step 2: Setting Up the PHP Container

Create a Dockerfile in the .docker/php directory with the following content:

FROM php:8.3.11-fpm
 
#Oppitional label
LABEL author="Dinesh Uprety"
 
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential libpng-dev libjpeg-dev libwebp-dev libxpm-dev libfreetype6-dev \
libzip-dev zip unzip git bash fcgiwrap libmcrypt-dev libonig-dev libpq-dev \
&& rm -rf /var/lib/apt/lists/*
 
# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install gd pdo pdo_pgsql mbstring zip exif pcntl bcmath opcache
 
# Install Composer
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer
 
# Copy application code
COPY . /var/www/html/
 
# Configure permissions and timezone
RUN groupadd -g 1000 www && useradd -u 1000 -ms /bin/bash -g www www \
&& ln -snf /usr/share/zoneinfo/Asia/Kathmandu /etc/localtime \
&& echo "Asia/Kathmandu" > /etc/timezone \
&& printf '[PHP]\ndate.timezone = "Asia/Kathmandu"\n' > /usr/local/etc/php/conf.d/tzone.ini
 
USER www
 
EXPOSE 9000
 
CMD ["php-fpm"]

For more information about the Dockerfile, click here to read an explanation by Sujan Shakya.

Step 3: Configuring Supervisor

Supervisor manages Laravel’s queue workers. The configuration is in .docker/php/supervisord.conf:

[program:laravel_worker]
process_name = %(program_name)s_%(process_num)02d
command = php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart = true
autorestart = true
stopasgroup = true
killasgroup = true
user = www
numprocs = 8
redirect_stderr = true
# Change this to your log file path
stdout_logfile = /var/www/html/.docker/php-supervisor/log/stdout_logfile.log
stopwaitsecs = 3600
 
[supervisord]
# Change this to your log file path
logfile = /var/www/html/.docker/php-supervisor/log/logfile.log
nodaemon = true
# Change this to your log file path
pidfile = /var/www/html/.docker/php-supervisor/log/pidfile.log

The Supervisor container uses its own Dockerfile located in .docker/php-supervisor/:

FROM php:8.3.11-fpm
 
# Update package list and install required libraries
RUN apt-get update && apt-get install -y \
supervisor \
libpq-dev \
&& docker-php-ext-install pdo_pgsql \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
 
# Create the www user and group
RUN groupadd -g 1000 www && useradd -u 1000 -ms /bin/bash -g www www
 
# Create directories for Supervisor configuration and logs
RUN mkdir -p /var/log/supervisor && chown -R www:www /var/log/supervisor
 
# Set working directory
WORKDIR /var/www/html
 
# Copy application code
COPY --chown=www:www . /var/www/html
 
# Optionally copy specific process configuration files
COPY ./php/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
 
# Default command to run Supervisor
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]

Step 4: Configuring Nginx

Create a default.conf file in the .docker/nginx directory with the following content:

server {
listen 80;
listen [::]:80;
server_name _;
root /var/www/html/public;
 
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
 
index index.php index.html index.htm;
 
charset utf-8;
 
location / {
try_files $uri $uri/ /index.php?$query_string;
}
 
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
 
error_page 404 /index.php;
 
location ~ ^/index\.php(/|$) {
# Change this to your app container name <laravel_11_app>
fastcgi_pass laravel_11_app:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
 
location ~ /\.(?!well-known).* {
deny all;
}
}

Step 5: Running the Containers

Run the following command in your project root to start the containers:

1. Start the containers:

docker-compose up --build -d

2. Access web application container

docker exec -it laravel_11_app bash

3. Run the following command to run the application

cp .env.example .env
 
composer install && php artisan key:generate && php artisan migrate && php artisan db:seed

4. Access the Application

Once the containers are up and running, open your web browser and navigate to: http://localhost:8080 This URL will provide access to the application.

Step 6: Managing the PostgreSQL Database

The PostgreSQL container is pre-configured with:

  • Database: laravel
  • User: root
  • Password: root

You can access the database using a PostgreSQL client or by running the following command:

docker exec -it laravel_11_db psql -U root laravel

You can connect using a database client like DBeaver or directly in Laravel by updating the .env file:

DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root

Conclusion

You have successfully set up a Laravel 11 project in Docker with Supervisor for managing background processes and PostgreSQL as the database. This setup provides a robust and scalable environment for developing and deploying Laravel applications.

References

Discussion

Login or register to comment or ask questions

No comments or questions yet...