مقاله

نصب لاراول با Docker Compose — راهنمای گام‌به‌گام با MySQL، Redis و Nginx

نصب لاراول با Docker Compose — راهنمای گام‌به‌گام با MySQL، Redis و Nginx

آموزش نصب Laravel 12 با Docker Compose: ساخت پروژه بدون PHP روی سیستم، Dockerfile برای PHP-FPM، کانفیگ Nginx، MySQL و Redis، تنظیم .env، migrate و queue worker — همه فایل‌ها کامل.

نصب Laravel با Docker Compose یعنی یک stack کامل (PHP-FPM، Nginx، MySQL، Redis و در صورت نیاز queue worker) را با یک compose.yaml بالا بیاورید — برخلاف مقاله intro که یک container و مفاهیم پایه است، و برخلاف Laravel Sail که Compose آماده رسمی با دستورهای کوتاه است. این راهنما برای کسانی است که می‌خواهند فایل‌های Compose/Nginx/Dockerfile را خودشان کنترل کنند (نزدیک‌تر به production). با docker compose up همه سرویس‌ها بالا می‌آیند؛ PHP یا Composer محلی لازم نیست.

خلاصه مراحل

  1. ساخت پروژه با image Composer
  2. Dockerfile PHP-FPM و کانفیگ Nginx
  3. compose.yaml برای app، nginx، mysql و redis
  4. تنظیم .env و اجرای migrate
  5. queue worker (اختیاری)

پیش‌نیازها

  • ویندوز: Docker Desktop با WSL2. برای سرعت بهتر، پروژه را داخل فایل‌سیستم WSL (مثلاً ~/projects) نگه دارید، نه روی درایو C.
  • لینوکس: Docker Engine به‌همراه پلاگین Compose.
  • بررسی نصب: docker compose version. در Compose نسخه ۲ دستور docker compose (با فاصله) است، نه docker-compose قدیمی.

نصب PHP یا Composer روی خود سیستم لازم نیست؛ همه‌چیز داخل containerها اجرا می‌شود.

ساختار فایل‌ها

my-app/
├── compose.yaml
├── docker/
│   ├── php/Dockerfile
│   └── nginx/default.conf
├── .env
└── (فایل‌های Laravel)

مرحله ۱ — ساخت پروژه Laravel با Docker

اگر PHP و Composer روی سیستم ندارید، پروژه را با image رسمی Composer بسازید:

docker run --rm -v "${PWD}:/app" -w /app composer:2 create-project laravel/laravel my-app "12.*"
cd my-app

این دستور در PowerShell و bash یکسان کار می‌کند. روی لینوکس برای اینکه فایل‌ها به نام کاربر خودتان ساخته شوند، --user "$(id -u):$(id -g)" را هم اضافه کنید. اگر Composer را روی ویندوز نصب کرده‌اید (نصب Composer روی ویندوز)، همان composer create-project معمولی هم کافی است.

مرحله ۲ — Dockerfile برای PHP-FPM

فایل docker/php/Dockerfile:

FROM php:8.3-fpm

RUN apt-get update && apt-get install -y \
    git unzip libzip-dev libpng-dev \
    && docker-php-ext-install pdo_mysql zip gd \
    && pecl install redis && docker-php-ext-enable redis \
    && rm -rf /var/lib/apt/lists/*

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

WORKDIR /var/www

اکستنشن redis لازم است چون Laravel به‌صورت پیش‌فرض با کلاینت phpredis به Redis وصل می‌شود. Laravel 12 به PHP 8.2 یا بالاتر نیاز دارد.

مرحله ۳ — کانفیگ Nginx

فایل docker/nginx/default.conf:

server {
    listen 80;
    root /var/www/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;
    }
}

app:9000 یعنی سرویس app در همین Compose که PHP-FPM روی پورت 9000 آن گوش می‌دهد. جزئیات بیشتر در کانفیگ Nginx برای Laravel.

مرحله ۴ — فایل compose.yaml

services:
  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    volumes:
      - .:/var/www
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_started

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

  mysql:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: rootsecret
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      retries: 10

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

volumes:
  mysql_data:

همه سرویس‌ها روی شبکه پیش‌فرض همین پروژه هستند و با نام سرویس (mysql، redis، app) همدیگر را پیدا می‌کنند. با condition: service_healthy، سرویس app تا آماده شدن MySQL صبر می‌کند. پورت‌های 3306 و 6379 فقط برای اتصال ابزارهایی مثل DBeaver از روی سیستم باز شده‌اند و برای کار Laravel لازم نیستند.

مرحله ۵ — تنظیم .env

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

REDIS_HOST=redis
CACHE_STORE=redis
QUEUE_CONNECTION=redis

پروژه تازه Laravel 12 روی SQLite تنظیم شده؛ اگر DB_CONNECTION=mysql را عوض نکنید، MySQL اصلاً استفاده نمی‌شود. hostname همان نام سرویس در compose است — نه 127.0.0.1، چون از داخل container، localhost خود همان container است. توضیح بقیه متغیرها در راهنمای فایل .env در Laravel.

مرحله ۶ — بالا آوردن و اولین اجرا

docker compose up -d --build
docker compose exec app php artisan migrate

حالا http://localhost:8080 را باز کنید. اگر پروژه را از Git کلون کرده‌اید و پوشه vendor یا APP_KEY ندارید، قبل از migrate این دو را هم اجرا کنید:

docker compose exec app composer install
docker compose exec app php artisan key:generate

روی لینوکس اگر خطای permission روی storage گرفتید: docker compose exec app chown -R www-data:www-data storage bootstrap/cache.

دستورات روزانه

docker compose up -d
docker compose exec app php artisan migrate
docker compose exec app composer require vendor/package
docker compose logs -f nginx
docker compose down

docker compose down داده MySQL را نگه می‌دارد؛ docker compose down -v volume را هم پاک می‌کند.

Queue worker در Compose

  queue:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    command: php artisan queue:work --sleep=3 --tries=3
    volumes:
      - .:/var/www
    depends_on:
      - mysql
      - redis

این بلوک را زیر services اضافه کنید. worker کد را یک‌بار در حافظه بارگذاری می‌کند؛ بعد از تغییر کد، docker compose restart queue بزنید. بیشتر درباره صف: Queue در Laravel و Redis و Horizon.

Node و Vite (اختیاری)

  node:
    image: node:22-alpine
    working_dir: /var/www
    volumes:
      - .:/var/www
    ports:
      - "5173:5173"
    command: sh -c "npm install && npm run dev -- --host"

اگر صفحه به سرور Vite وصل نشد، در vite.config.js مقدار server.hmr.host را 'localhost' بگذارید.

Sail یا Compose دستی؟

Laravel Sail راه رسمی Laravel برای همین کار است: یک Compose آماده با دستورهای کوتاه. با composer require laravel/sail --dev و php artisan sail:install نصب می‌شود و با ./vendor/bin/sail up بالا می‌آید. Compose دستی این راهنما کنترل کامل روی سرویس‌ها و نسخه‌ها می‌دهد و ساختارش به production نزدیک‌تر است.

اشتباهات رایج

  • DB_HOST=127.0.0.1 داخل app container
  • عوض نکردن DB_CONNECTION از sqlite به mysql
  • نصب نکردن اکستنشن redis در Dockerfile و خطای «Class Redis not found»
  • اجرای down -v بدون بکاپ و از دست دادن داده MySQL
  • استفاده از همین Compose توسعه برای production بدون hardening

سؤالات متداول

پورت 3306 یا 8080 اشغال است؛ چه کنم؟

پورت سمت سیستم را عوض کنید، مثلاً "3307:3306" یا "8081:80". پورت داخل container همان می‌ماند.

روی ویندوز کند است؛ چرا؟

mount پوشه‌ای از درایو C در WSL2 کند است. پروژه را داخل فایل‌سیستم WSL بگذارید و از همان‌جا docker compose up بزنید.

scheduler را چطور اجرا کنم؟

یک سرویس جدا با همان build و دستور php artisan schedule:work اضافه کنید.

docker-compose.yml یا compose.yaml؟

هر دو خوانده می‌شوند؛ compose.yaml نام پیشنهادی فعلی است.

جمع‌بندی

با این چهار فایل — Dockerfile، کانفیگ Nginx، compose.yaml و .env — کل محیط توسعه Laravel با یک دستور بالا می‌آید و برای همه اعضای تیم یکسان است. برای انتشار روی سرور، Deploy Laravel روی Ubuntu و SSL با Let's Encrypt را ببینید.

راه‌اندازی Docker برای پروژه‌تان

اشتراک‌گذاری