DEV
Home About Services Projects Blog Contact
Hire me
DevOps & Déploiement

Dockerizing Your Laravel Application in 2025: Zero Pain, Zero Surprises

🇫🇷 Lire en français
Dockerizing Your Laravel Application in 2025: Zero Pain, Zero Surprises

"It works on my machine." In a development team, this phrase is almost a joke. Almost, because it causes real disasters. The app works perfectly locally, then goes to production and refuses to start. PHP 7.4 locally, PHP 8.2 in prod. MySQL 5.7 locally, MySQL 8.0 in prod. This kind of inconsistency has cost me entire nights of debugging.

Docker eliminates this problem. Here's how to dockerize a Laravel application properly.

Understanding Docker in 2 Minutes

Docker is not a virtual machine. It's a system of lightweight containers that package your application with exactly the environment it needs: the right PHP version, the right extensions, the right environment variables. Nothing more, nothing less.

  • Image — an immutable template (e.g.: PHP 8.3 + Laravel extensions)
  • Container — a running instance of an image
  • docker-compose — orchestration of multiple containers (PHP + MySQL + Redis)
  • Volume — data persistence outside the container

The Dockerfile for Laravel

FROM php:8.3-fpm-alpine

RUN apk add --no-cache \
    libpng-dev \
    libzip-dev \
    oniguruma-dev \
    && docker-php-ext-install \
        pdo_mysql \
        mbstring \
        zip \
        gd \
        opcache

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

WORKDIR /var/www/html

COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts

COPY . .

RUN chown -R www-data:www-data storage bootstrap/cache \
    && chmod -R 775 storage bootstrap/cache

EXPOSE 9000
CMD ["php-fpm"]

The docker-compose.yml: Orchestrating the Full Environment

version: '3.8'

services:
  app:
    build: .
    container_name: laravel_app
    volumes:
      - .:/var/www/html
    networks:
      - laravel
    depends_on:
      - db
      - redis

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - .:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    networks:
      - laravel

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel

  redis:
    image: redis:alpine
    networks:
      - laravel

networks:
  laravel:
    driver: bridge

volumes:
  db_data:

Starting the Project in One Command

# Launch all containers in the background
docker-compose up -d

# Install Laravel dependencies
docker-compose exec app composer install

# Configure the application
docker-compose exec app php artisan key:generate
docker-compose exec app php artisan migrate --seed

Concrete Benefits for Your Workflow

  • 5-minute onboarding — a new dev clones the repo, runs docker-compose up, it's ready
  • Identical environments — dev, staging, production all use the same Dockerfile
  • Full isolation — each project has its own PHP and MySQL versions
  • Simplified CI/CD — your GitHub Actions pipeline uses the same container

Conclusion

Adopting Docker for your Laravel projects is no longer optional if you work in a team or deploy regularly. The initial investment (one to two hours to configure everything) pays off immediately when you avoid your first environment conflict.

And trust me, someday you'll inevitably avoid that all-nighter wondering why it "worked on your machine."

Related articles

Écrire sur WhatsApp