Installing and Setting Up Laravel with Docker Compose on Ubuntu 22.04 — A Comprehensive Guide
In this step-by-step guide, learn how to install and configure Laravel using Docker Compose on Ubuntu 22.04 and create a secure and optimized production environment.

Installing and Setting Up Laravel with Docker Compose on Ubuntu 22.04 — A Comprehensive Guide

This article will show you how to install and deploy a Laravel application on Ubuntu 22.04 using Docker Compose. By taking you through the process step by step, you can easily create a secure and optimized production environment.
0 Shares
0
0
0
0

How to install and set up Laravel with Docker Compose on Ubuntu 22.04?

In this practical and technical guide, we will walk you through the step-by-step process of installing and configuring an application. Laravel Using Docker Compose On the server Ubuntu 22.04 The goal of this article is to provide repeatable guidelines for developers, DevOps teams, and technical managers to create a secure, scalable, and maintainable production environment.

Initial checklist

Before you begin, prepare the following:

  • A server Ubuntu 22.04 With root access or a user with sudo
  • Docker (stable version) and Docker Compose (or use docker compose plugin)
  • Open ports: 80/443 For the web; if needed 3306 Or 5432 For database (preferably limited to IPs)
  • Adequate disk space (SSD recommended) and access to one of more than 85 locations Global if using cloud services
  • Domain name and DNS record pointing to the server IP

Installing Docker and Docker Compose on Ubuntu 22.04

Run the following commands on the server to install Docker and the docker compose plugin:

sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER

Then log out and log back in or newgrp docker Use.

To check the installation:

docker --version
docker compose version

Proposed project structure

It is recommended that the project folder be organized as follows to make maintenance and development easier:

  • project-root/
    • docker/
      • nginx/default.conf
      • php/Dockerfile
    • src/ — Laravel code (or mount)
    • docker-compose.yml
    • .env

Recommended Dockerfile for PHP-FPM (PHP 8.1)

A file with a path docker/php/Dockerfile Create something like the following example:

FROM php:8.1-fpm

# Install required tools and extensions
RUN apt-get update && apt-get install -y \
    git zip unzip libpng-dev libjpeg-dev libfreetype6-dev libonig-dev libxml2-dev \
    libzip-dev libpq-dev cron curl supervisor \
  && docker-php-ext-configure gd --with-freetype --with-jpeg \
  && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql pdo_pgsql mbstring xml bcmath zip opcache \
  && pecl install redis && docker-php-ext-enable redis \
  && pecl install xdebug || true \
  && apt-get clean && rm -rf /var/lib/apt/lists/*

# Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

# Create non-root user
RUN useradd -G www-data,root -u 1000 -d /home/appuser appuser
WORKDIR /var/www/html
USER appuser

docker-compose.yml example

Suggested version docker-compose.yml To run the application, web server, database, and Redis:

version: "3.8"

services:
  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    image: laravel_app:latest
    container_name: laravel_app
    restart: unless-stopped
    volumes:
      - ./src:/var/www/html
      - ./docker/php/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf
    environment:
      - APP_ENV=production
      - APP_DEBUG=false
    networks:
      - laravel-net

  web:
    image: nginx:alpine
    container_name: laravel_web
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./src:/var/www/html:ro
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs:/etc/letsencrypt
    depends_on:
      - app
    networks:
      - laravel-net

  db:
    image: mysql:8.0
    container_name: laravel_db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel-net

  redis:
    image: redis:6-alpine
    container_name: laravel_redis
    restart: unless-stopped
    volumes:
      - redis_data:/data
    networks:
      - laravel-net

volumes:
  db_data:
  redis_data:

networks:
  laravel-net:
    driver: bridge

Nginx configuration file (docker/nginx/default.conf)

Example Nginx configuration to route requests to PHP-FPM (app):

server {
    listen 80;
    server_name example.com;

    root /var/www/html/public;
    index index.php index.html;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.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 ~ /\.ht {
        deny all;
    }
}

Note: In architectures with reverse proxy or multiple services, you can put Nginx at the load balancer or CDN layer.

Preparing the code and installing dependencies

If you don't have a Laravel project, you can create a new one with Composer:

composer create-project --prefer-dist laravel/laravel src

Then to build and run containers:

docker compose build
docker compose up -d

To run Composer and Artisan commands inside a PHP container:

docker exec -it laravel_app bash
composer install --no-dev --optimize-autoloader
php artisan key:generate
php artisan migrate --force
php artisan config:cache
php artisan route:cache
exit

Setting up the .env file for Docker

Example .env configuration compatible with docker-compose:

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret

CACHE_DRIVER=redis
REDIS_HOST=redis

APP_URL=https://example.com

SSL and Let's Encrypt — Two Easy Ways

There are two simple ways to enable HTTPS:

  • Using Certbot on the host: Stop Nginx temporarily, place the issued certificate in the folder ./certs and mount it to the container.
  • Using the automated solution: Tools like docker-letsencrypt-nginx-proxy-companion Or Traffic They are suitable for automated certificate management.

Quick example with Certbot:

sudo apt install -y certbot
sudo docker compose down
sudo certbot certonly --standalone -d example.com --non-interactive --agree-tos -m [email protected]
# Copy certificates from /etc/letsencrypt/live/... to ./certs and then:
sudo docker compose up -d

Launch at boot and maintain service

To ensure services run after reboot:

sudo systemctl enable docker

Additionally, in docker-compose from restart: unless-stopped It has been used. If needed, a systemd unit can be created for docker-compose.

Practical security tips

  • Using a non-root user in a PHP container (appuser in the Dockerfile above)
  • Restricting access to the database port with firewall (UFW):
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable

Other recommendations:

  • Regular backup of the database volume (db_data) and storing it outside the server
  • Enabling HTTPS and HSTS
  • Using secrets or key management services to store passwords (Docker secrets or key management services)
  • Use security tools such as fail2ban And if needed WAF like ModSecurity
  • Using a CDN or Anti-DDoS service to protect traffic

Performance optimization for production environments

  • Enabling OPcache in php.ini:
    opcache.memory_consumption=256
    opcache.validate_timestamps=0
  • Setting up php-fpm (pm = dynamic or ondemand) and increasing max_children According to server memory
  • Using Redis for cache and sessions
  • Using a CDN for static files
  • Horizontal scaling: running multiple instances of the app service with a load balancer (NGINX or HAProxy)
  • Use separate workers and supervisors or services for real-time and queues.

Queue workers and Horizon

Add a separate service in docker-compose to run queue workers. Example:

worker:
  build: ...
  command: php /var/www/html/artisan queue:work --sleep=3 --tries=3
  depends_on: [app, redis]
  restart: unless-stopped

For Laravel Horizon it is best to use a dedicated container with PHP and Horizon installed and place it behind Nginx/authentication.

Tips related to location and data center selection

Practical tips for choosing a location:

  • For the lowest latency, choose a server in a location close to your end users or destination. The service provider is more than 85 global locations It has.
  • For gamers or traders, choose a location with low ping and an optimized BGP network.
  • Use GPU-equipped servers for AI processing and rendering.
  • Use servers and CDN with Anti-DDoS protection to resist DDoS.

Backups, monitoring, and logs

  • Container logs with docker logs Are accessible; use ELK or Prometheus+Grafana for central aggregation.
  • Daily database backup and periodic restore test
  • Monitoring CPU/RAM resources, application and error tracking in CI/CD

Common debugging

  • 502 Bad Gateway Error: Check that php-fpm is running in the app container and that fastcgi_pass is set to the correct address (app:9000) to point out.
  • Database connection problem: Check .env variables, docker network, and MySQL logs.
  • File permissions: In case of permission errors, set ownership of the storage and bootstrap/cache folders:
sudo chown -R 1000:1000 src/storage src/bootstrap/cache

Conclusion and final recommendation

Using Docker Compose to run Laravel on Ubuntu 22.04 makes development and deployment simple, repeatable, and scalable. By following this guide, you can set up a secure, fast, and maintainable production environment: PHP-FPM with Nginx, MySQL/MariaDB or PostgreSQL, Redis for cache and queue, and SSL settings and monitoring.

Related services

To professionally implement this architecture, you can use the following services:

  • More than 85 global locations To reduce latency and bring the server closer to the user or destination
  • Graphics server (GPU) for AI computing and rendering
  • VPS for trading with low ping and optimized BGP network
  • Gaming VPS with low ping and Anti-DDoS
  • Hosting and domain registration services, CDN, network and BGP solutions
  • High-performance cloud server and managed backup

Frequently Asked Questions

You May Also Like
How-to-Install-Cockpit-on-Ubuntu-24.04

How to install Cockpit on Ubuntu 24.04

Cockpit is a web-based management panel for servers that allows for monitoring, managing services, storage, logs, and users in a simple, graphical way. Using Cockpit on a VPS allows system administrators to perform many server administration tasks without the need for a command line. Below, we will walk you through how to install, configure security, and access Cockpit step by step.