Run Laravel 11 With Docker, Supervisor, And Postgresql For A Scalable Development Setup
Published on December 21, 2024 by Dinesh Uprety
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:
- Docker and Docker Compose installed on your system.
- 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 labelLABEL author="Dinesh Uprety" # Install dependenciesRUN 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 extensionsRUN 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 ComposerCOPY --from=composer/composer:latest-bin /composer /usr/bin/composer # Copy application codeCOPY . /var/www/html/ # Configure permissions and timezoneRUN 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)02dcommand = php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600autostart = trueautorestart = truestopasgroup = truekillasgroup = trueuser = wwwnumprocs = 8redirect_stderr = true# Change this to your log file pathstdout_logfile = /var/www/html/.docker/php-supervisor/log/stdout_logfile.logstopwaitsecs = 3600 [supervisord]# Change this to your log file pathlogfile = /var/www/html/.docker/php-supervisor/log/logfile.lognodaemon = true# Change this to your log file pathpidfile = /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 librariesRUN 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 groupRUN groupadd -g 1000 www && useradd -u 1000 -ms /bin/bash -g www www # Create directories for Supervisor configuration and logsRUN mkdir -p /var/log/supervisor && chown -R www:www /var/log/supervisor # Set working directoryWORKDIR /var/www/html # Copy application codeCOPY --chown=www:www . /var/www/html # Optionally copy specific process configuration filesCOPY ./php/supervisord.conf /etc/supervisor/conf.d/supervisord.conf # Default command to run SupervisorCMD ["/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=pgsqlDB_HOST=dbDB_PORT=5432DB_DATABASE=laravelDB_USERNAME=rootDB_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.