Laravel Sail harika bir başlangıç noktasıdır ama production ortamından çok uzaklaşır ve özelleştirmek güçleşir. Bu yazıda, production'daki nginx + PHP-FPM + Redis + MySQL yapısını bire bir yansıtan özel bir Docker Compose kurulumunu adım adım anlatıyorum.

Proje Yapısı

projem/
├── docker/
│   ├── nginx/
│   │   └── default.conf
│   └── php/
│       ├── Dockerfile
│       └── php.ini
├── docker-compose.yml
└── (Laravel uygulama dosyaları)

docker-compose.yml

version: '3.8'
services:
  app:
    build: ./docker/php
    volumes:
      - .:/var/www/html
    depends_on: [mysql, redis]
    environment:
      - APP_ENV=local

  nginx:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - .:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on: [app]

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  queue:
    build: ./docker/php
    command: php artisan queue:work --sleep=3 --tries=3
    volumes:
      - .:/var/www/html
    depends_on: [app, redis]

volumes:
  mysql_data:

PHP Dockerfile

FROM php:8.3-fpm-alpine

RUN apk add --no-cache git curl libpng-dev libjpeg-dev \
    && docker-php-ext-install pdo_mysql gd bcmath opcache

RUN curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer

COPY php.ini /usr/local/etc/php/conf.d/custom.ini

WORKDIR /var/www/html

Nginx Konfigürasyonu

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

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

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Faydalı Komutlar

# Ortamı başlat
docker compose up -d

# Artisan komutları çalıştır
docker compose exec app php artisan migrate
docker compose exec app php artisan tinker

# Composer
docker compose exec app composer install

# Logları izle
docker compose logs -f app

Production'a Geçiş Farkları

  • Production'da APP_ENV=production ve APP_DEBUG=false
  • Volumes yerine COPY komutu ile uygulama kodunu image'a gömin
  • Multi-stage build ile image boyutunu küçültün
  • Health check ekleyin: healthcheck: test: ["CMD", "php-fpm-healthcheck"]
  • Secrets yönetimi için Docker Secrets veya Vault kullanın