Docker for PHP Developers: Local Development Setup

Learn Docker from basics to advanced concepts with practical examples for PHP and Laravel development, including multi-container setups and production deployment.

S

StalkTechie

Author

October 6, 2025
850 views

Docker for PHP Developers: Local Development Setup

Docker simplifies PHP development by providing consistent, isolated environments across machines. This guide covers Docker basics, containerizing PHP apps (especially Laravel), multi-service setups with Docker Compose, volume management, optimization, and tips for production deployment. Ideal for Laravel, Symfony, or plain PHP projects in 2025 with Docker 27.x+.

Docker Basics and Installation

Docker uses containers (lightweight VMs) to package apps with dependencies.

  • Images: Blueprints (e.g., php:8.3-fpm).
  • Containers: Running instances.
  • Volumes: Persistent data.
  • Networks: Communication between containers.

Install Docker Desktop (Windows/Mac) or Docker Engine (Linux). Enable WSL2 on Windows.


# Test installation
docker --version
docker run hello-world
    

Key commands: docker build, docker run, docker ps, docker exec, docker compose.

Containerizing a Simple PHP App

Create a Dockerfile for a basic PHP script.


# Dockerfile
FROM php:8.3-cli  # Base image

WORKDIR /app
COPY . /app

CMD ["php", "index.php"]
    

<?php // index.php
echo "Hello from Docker PHP!";
    

Build and run:


docker build -t my-php-app .
docker run --rm my-php-app
    

For web apps, use php:8.3-apache or fpm with Nginx.

Docker for Laravel: Multi-Container Setup

Use Docker Compose for app, web server, DB, and cache.

Directory Structure


my-laravel-app/
├── app/ (Laravel code)
├── docker/
│   ├── php/Dockerfile
│   ├── nginx/nginx.conf
│   └── mysql/my.cnf
├── docker-compose.yml
    

PHP Dockerfile


FROM php:8.3-fpm

# Install dependencies
RUN apt-get update && apt-get install -y \
    libpng-dev libjpeg-dev zip unzip git \
    && docker-php-ext-install pdo_mysql gd

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

WORKDIR /var/www
COPY app /var/www
RUN composer install --optimize-autoloader --no-dev
RUN chown -R www-data:www-data /var/www

CMD ["php-fpm"]
    

Nginx Config


server {
    listen 80;
    index index.php;
    server_name localhost;
    root /var/www/public;

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

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
    

docker-compose.yml


version: '3.9'
services:
  php:
    build: ./docker/php
    volumes:
      - ./app:/var/www
    networks: [app-network]

  nginx:
    image: nginx:latest
    ports: ["8000:80"]
    volumes:
      - ./app:/var/www
      - ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on: [php]
    networks: [app-network]

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    volumes:
      - db-data:/var/lib/mysql
    ports: ["3306:3306"]
    networks: [app-network]

  redis:
    image: redis:alpine
    networks: [app-network]

networks:
  app-network:
    driver: bridge

volumes:
  db-data:
    

Start: docker compose up -d. Access app at http://localhost:8000. Run Artisan: docker compose exec php php artisan migrate.

For Laravel env: Copy .env.example, set DB_HOST=mysql.

Volume Management and Data Persistence

  • Bind mounts: ./app:/var/www for code syncing.
  • Named volumes: For DB to persist data.
  • Anonymous volumes: For temp caches.

Cleanup: docker volume prune. Backup: docker compose down -v.

Optimization and Best Practices

  • Multi-Stage Builds: Separate build/runtime for smaller images.
  • 
    FROM composer as builder
    COPY . /app
    RUN composer install --no-dev
    
    FROM php:8.3-fpm
    COPY --from=builder /app /var/www
            
  • .dockerignore: Exclude node_modules, .git, .env.
  • Healthchecks: Add to compose: healthcheck: { test: ["CMD", "curl", "-f", "http://localhost"] }.
  • Security: Run as non-root: USER 1000. Scan images with Trivy.
  • Performance: Use Alpine images for smaller size; cache layers in Dockerfile.
  • Env Vars: Use .env files with compose: env_file: .env.

Debugging and Tools

  • Logs: docker compose logs -f php.
  • Shell: docker compose exec php bash.
  • Xdebug: Add to Dockerfile pecl install xdebug && docker-php-ext-enable xdebug; configure in php.ini.
  • VS Code: Docker extension for building/running.
  • Portainer: Web UI for management.

Production Deployment

  • Docker Swarm/Kubernetes: For orchestration. Use docker stack deploy.
  • CI/CD: GitHub Actions: Build image, push to Docker Hub/ECR, deploy to ECS/Heroku.
  • Reverse Proxy: Add Traefik or Nginx Proxy Manager.
  • SSL: Use Let's Encrypt with Certbot in containers.
  • Scaling: docker compose up --scale php=3.
  • Monitoring: Prometheus + Grafana; watch CPU/memory with docker stats.

Platforms: Render, Fly.io, or AWS ECS for easy PHP Docker deploys.

Common Issues and Fixes

  • File Permissions: Use chmod -R 777 storage or www-data user.
  • Port Conflicts: Change host ports in compose.
  • Windows Path Issues: Use Linux containers.
  • Composer Slow: Cache volumes ~/.composer:/tmp/composer.

Advanced: Custom Images and Extensions

Build PHP with extensions like Redis: pecl install redis && docker-php-ext-enable redis.

For Node frontend: Add node service in compose.

Docker streamlines PHP dev - consistent envs reduce "works on my machine" issues. Start with Sail (Laravel's Docker setup: curl -s https://laravel.build/app | bash) for quickstarts. Scale to orchestration as needed!

Share this post:

Related Articles

Discussion

0 comments

Please log in to join the discussion.

Login to Comment