Docker

Deploy Laravel App ด้วย Docker และ MySQL ครบทุกขั้นตอน

เผยแพร่ · แก้ไขล่าสุด

ทำไมต้อง Deploy Laravel ด้วย Docker?

การ Deploy Laravel ผ่าน Docker ช่วยให้ทีมทุกคนใช้ Environment เดียวกัน ย้าย Server ได้ง่าย และไม่มีปัญหา "works on my machine" อีกต่อไป

โครงสร้าง Project

laravel-docker/
├── app/              # Laravel source code
├── docker/
│   ├── nginx/
│   │   └── default.conf
│   └── php/
│       └── Dockerfile
├── .env.docker
└── docker-compose.yml

Dockerfile สำหรับ Laravel (PHP 8.2)

FROM php:8.2-fpm-alpine

# ติดตั้ง Dependencies
RUN apk add --no-cache \
    libpng-dev \
    libjpeg-turbo-dev \
    libwebp-dev \
    zip \
    libzip-dev \
    unzip \
    nodejs \
    npm

# ติดตั้ง PHP Extensions
RUN docker-php-ext-install \
    pdo \
    pdo_mysql \
    zip \
    gd \
    bcmath \
    opcache

# ติดตั้ง Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

# คัดลอก Composer dependencies
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader

# Copy source code
COPY . .
RUN composer dump-autoload --optimize

# Permissions
RUN chown -R www-data:www-data storage bootstrap/cache

EXPOSE 9000
CMD ["php-fpm"]

Nginx config (docker/nginx/default.conf)

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_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

docker-compose.yml

version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    container_name: laravel_app
    restart: unless-stopped
    volumes:
      - .:/var/www/html
      - /var/www/html/vendor
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      APP_ENV: production
      APP_KEY: ${APP_KEY}
      DB_HOST: mysql
      DB_DATABASE: ${DB_DATABASE}
      DB_USERNAME: ${DB_USERNAME}
      DB_PASSWORD: ${DB_PASSWORD}
      REDIS_HOST: redis
      CACHE_DRIVER: redis
      SESSION_DRIVER: redis

  nginx:
    image: nginx:1.25-alpine
    container_name: laravel_nginx
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - .:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

  mysql:
    image: mysql:8.0
    container_name: laravel_mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  redis:
    image: redis:7-alpine
    container_name: laravel_redis
    restart: unless-stopped
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

volumes:
  mysql_data:
  redis_data:

ไฟล์ .env.docker

APP_NAME=MyLaravel
APP_ENV=production
APP_KEY=base64:your-app-key-here
APP_DEBUG=false
APP_URL=https://yourdomain.com

DB_ROOT_PASSWORD=rootpassword
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=securepassword

Deploy ครั้งแรก

# Copy .env
cp .env.docker .env

# Build และ Start
docker compose up -d --build

# Generate App Key
docker exec laravel_app php artisan key:generate

# Run Migrations
docker exec laravel_app php artisan migrate --force

# Clear Cache
docker exec laravel_app php artisan config:cache
docker exec laravel_app php artisan route:cache
docker exec laravel_app php artisan view:cache

Queue Worker

  queue:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    command: php artisan queue:work --sleep=3 --tries=3 --max-time=3600
    restart: unless-stopped
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy

สรุป

การ Deploy Laravel ด้วย Docker ให้ความยืดหยุ่นและเสถียรภาพสูง สามารถ Scale เพิ่ม Worker ได้ง่ายโดยไม่ต้องแก้ไข Server เลย