راه‌اندازی یک پشته LEMP با Docker Compose: آموزش گام به گام با نمونه کد

فهرست مطالب

در دنیای پرشتاب توسعه وب مدرن، نیاز به محیط‌های توسعه و استقرار کارآمد، قابل تکرار و ایزوله بیش از پیش احساس می‌شود. پشته LEMP (Linux, Nginx, MariaDB/MySQL, PHP) یکی از محبوب‌ترین و قدرتمندترین ترکیب‌ها برای میزبانی برنامه‌های وب پویا است. از سوی دیگر، داکر (Docker) و داکر کامپوز (Docker Compose) ابزارهایی انقلابی هستند که فرایند کانتینرسازی و مدیریت سرویس‌های چندکانتینری را به سادگی هر چه تمام‌تر ممکن می‌سازند. این ترکیب برنده به شما اجازه می‌دهد تا کل محیط توسعه و تولید خود را به صورت کدی تعریف کرده، به راحتی آن را بین توسعه‌دهندگان به اشتراک بگذارید، و از سازگاری کامل در محیط‌های مختلف اطمینان حاصل کنید.

این مقاله یک راهنمای جامع و گام به گام برای راه‌اندازی یک پشته کامل LEMP با استفاده از Docker Compose است. ما به شما نشان خواهیم داد که چگونه هر یک از اجزای این پشته را به صورت کانتینری درآورید، چگونه آن‌ها را پیکربندی کنید تا با یکدیگر ارتباط برقرار کنند، و چگونه کل سیستم را با یک فایل docker-compose.yml مدیریت کنید. هدف ما ارائه یک آموزش عملی و قابل فهم برای توسعه‌دهندگان، مدیران سیستم و هر کسی است که به دنبال افزایش بهره‌وری و انعطاف‌پذیری در مدیریت زیرساخت‌های وب خود است.

در طول این مقاله، ما به جزئیات فنی هر مولفه خواهیم پرداخت، نمونه کدهای کاربردی ارائه خواهیم داد و بهترین شیوه‌ها را برای پایداری داده‌ها، امنیت و بهینه‌سازی عملکرد مورد بحث قرار خواهیم داد. با اتمام این راهنما، شما نه تنها یک پشته LEMP کاملاً عملیاتی خواهید داشت، بلکه درک عمیق‌تری از قدرت و انعطاف‌پذیری Docker Compose در مدیریت محیط‌های پیچیده خواهید یافت. آماده شوید تا محیط توسعه خود را متحول کنید و به دنیای کانتینرهای ایزوله و قابل تکرار قدم بگذارید.

مقدمه‌ای بر پشته LEMP و Docker Compose: چرا و چگونه؟

قبل از اینکه به جزئیات فنی شیرجه بزنیم، اجازه دهید نگاهی دقیق‌تر به اجزای اصلی این آموزش بیندازیم: پشته LEMP و ابزارهای Docker و Docker Compose.

پشته LEMP چیست؟

LEMP یک پشته نرم‌افزاری متن‌باز است که به طور گسترده برای میزبانی برنامه‌های وب پویا مورد استفاده قرار می‌گیرد. این مخفف از اجزای زیر تشکیل شده است:

  • Linux: سیستم عامل زیربنایی که تمام اجزای دیگر روی آن اجرا می‌شوند.
  • Engine-x (Nginx): یک سرور وب پرسرعت، سبک و کارآمد که به عنوان یک پروکسی معکوس (reverse proxy) نیز عمل می‌کند و درخواست‌های HTTP را مدیریت می‌نماید. Nginx به دلیل توانایی خود در هندل کردن تعداد بالای ارتباطات همزمان و مصرف کم منابع، محبوبیت زیادی پیدا کرده است.
  • MariaDB/MySQL: یک سیستم مدیریت پایگاه داده رابطه‌ای (RDBMS) قدرتمند و متن‌باز. این پایگاه داده وظیفه ذخیره و بازیابی داده‌های برنامه وب شما را بر عهده دارد. MariaDB فورکی از MySQL است که به دلیل عملکرد بهتر و ویژگی‌های اضافه، به طور فزاینده‌ای مورد استفاده قرار می‌گیرد.
  • PHP: یک زبان اسکریپت‌نویسی سمت سرور که برای توسعه وب استفاده می‌شود. PHP کدهای برنامه وب شما را پردازش می‌کند و محتوای پویا را تولید می‌نماید. در پشته LEMP، PHP معمولاً از طریق FastCGI Process Manager (PHP-FPM) اجرا می‌شود که با Nginx ارتباط برقرار می‌کند.

ترکیب این چهار جزء یک بستر قدرتمند، انعطاف‌پذیر و مقیاس‌پذیر برای تقریباً هر نوع برنامه وب، از وبلاگ‌های ساده گرفته تا پلتفرم‌های پیچیده تجارت الکترونیک، فراهم می‌کند.

Docker و Docker Compose: نیروی محرکه کانتینرسازی

Docker یک پلتفرم متن‌باز است که توسعه‌دهندگان را قادر می‌سازد تا برنامه‌ها را به همراه تمام وابستگی‌هایشان در واحدهای ایزوله و قابل حمل به نام کانتینر بسته‌بندی کنند. کانتینرها تضمین می‌کنند که برنامه شما در هر محیطی که Docker نصب شده باشد، به طور یکسان اجرا می‌شود.

Docker Compose ابزاری برای تعریف و اجرای برنامه‌های چند کانتینری Docker است. با استفاده از یک فایل YAML، می‌توانید تمام سرویس‌های برنامه خود را پیکربندی کنید (مانند Nginx، PHP، پایگاه داده)، نحوه ارتباط آن‌ها با یکدیگر را مشخص کنید و سپس با یک دستور واحد، کل برنامه را بالا بیاورید یا پایین بکشید.

چرا پشته LEMP را با Docker Compose استفاده کنیم؟

ترکیب LEMP با Docker Compose مزایای قابل توجهی دارد:

  • ایزوله‌سازی: هر سرویس (Nginx, PHP, MariaDB) در کانتینر ایزوله خود اجرا می‌شود. این بدان معناست که تغییرات در یک سرویس بر دیگری تأثیر نمی‌گذارد و مدیریت وابستگی‌ها آسان‌تر می‌شود.
  • قابلیت تکرارپذیری: محیط توسعه شما دقیقاً مانند محیط تولید خواهد بود. این امر مشکلات “در سیستم من کار می‌کند!” را از بین می‌برد. فایل docker-compose.yml به عنوان یک طرح کلی (blueprint) عمل می‌کند که تضمین می‌کند هر کس که پروژه را راه‌اندازی کند، دقیقاً همان محیط را خواهد داشت.
  • پرتابل بودن: محیط LEMP شما کاملاً پرتابل است. می‌توانید کل پروژه را به هر ماشینی که Docker و Docker Compose روی آن نصب شده است، منتقل کرده و بلافاصله آن را اجرا کنید.
  • مدیریت آسان: با یک دستور docker-compose up، کل پشته LEMP شما بالا می‌آید. با docker-compose down، همه سرویس‌ها به طور منظم متوقف و حذف می‌شوند. این مدیریت چرخه حیات برنامه را به شدت ساده می‌کند.
  • توسعه موازی: می‌توانید چندین پروژه LEMP را با نسخه‌های مختلف PHP، Nginx و پایگاه داده روی یک ماشین اجرا کنید بدون اینکه تداخلی با یکدیگر داشته باشند.
  • مقیاس‌پذیری: اگرچه Docker Compose به خودی خود برای مقیاس‌بندی تولید در مقیاس بزرگ طراحی نشده است (برای آن باید از Docker Swarm یا Kubernetes استفاده کرد)، اما بنیاد لازم برای این کار را فراهم می‌کند و به شما اجازه می‌دهد تا سرویس‌های خاصی را به راحتی تکثیر کنید.

در ادامه، گام به گام نحوه راه‌اندازی این پشته قدرتمند را بررسی خواهیم کرد.

پیش‌نیازها و آماده‌سازی محیط

قبل از اینکه شروع به نوشتن کد کنیم، باید مطمئن شویم که ابزارهای لازم روی سیستم شما نصب شده‌اند و محیط کار برای پروژه آماده است.

نصب Docker و Docker Compose

شما نیاز دارید که Docker Engine و Docker Compose روی سیستم خود نصب شده باشند. دستورالعمل‌های نصب ممکن است بسته به سیستم عامل شما متفاوت باشد. در اینجا خلاصه‌ای از دستورالعمل‌ها برای سیستم‌عامل‌های مبتنی بر لینوکس (مانند Ubuntu) آورده شده است. برای سایر سیستم‌عامل‌ها (Windows, macOS)، بهتر است به مستندات رسمی Docker مراجعه کنید.

برای لینوکس (Ubuntu/Debian):


# بروزرسانی لیست پکیج‌ها
sudo apt-get update

# نصب پکیج‌های پیش‌نیاز
sudo apt-get install ca-certificates curl gnupg lsb-release -y

# اضافه کردن کلید GPG رسمی Docker
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# اضافه کردن مخزن Docker به APT
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# بروزرسانی لیست پکیج‌ها (پس از اضافه کردن مخزن Docker)
sudo apt-get update

# نصب Docker Engine، containerd و Docker Compose
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

# اطمینان از اجرای سرویس Docker
sudo systemctl start docker
sudo systemctl enable docker

# اضافه کردن کاربر فعلی به گروه Docker برای اجرای دستورات بدون sudo
sudo usermod -aG docker $USER

# برای اعمال تغییرات گروه، باید یک ترمینال جدید باز کنید یا دستور زیر را اجرا کنید
newgrp docker

# بررسی نسخه Docker و Docker Compose
docker --version
docker compose version

پس از اجرای دستور newgrp docker، اطمینان حاصل کنید که ترمینال جدیدی را باز کرده‌اید تا تغییرات گروه اعمال شوند. اگر از Windows یا macOS استفاده می‌کنید، نصب Docker Desktop ساده‌ترین راه برای نصب Docker و Docker Compose است.

ساختار پروژه پیشنهادی

برای حفظ نظم و خوانایی پروژه، پیشنهاد می‌شود یک ساختار دایرکتوری مشخص ایجاد کنید. این ساختار به ما کمک می‌کند تا فایل‌های پیکربندی هر سرویس و کدهای برنامه را به طور جداگانه نگهداری کنیم.


lemp-stack/
├── nginx/                          # دایرکتوری برای پیکربندی Nginx
│   └── default.conf                # فایل پیکربندی Nginx
├── php/                            # دایرکتوری برای Dockerfile PHP-FPM
│   └── Dockerfile                  # Dockerfile برای ساخت ایمیج PHP-FPM
├── app/                            # دایرکتوری برای کدهای برنامه وب شما (مثلاً یک برنامه PHP)
│   └── public/                     # (اختیاری) دایرکتوری عمومی وب
│       └── index.php               # فایل تست PHP
│   └── .env.example                # نمونه فایل متغیرهای محیطی
├── mariadb/                        # دایرکتوری اختیاری برای پیکربندی MariaDB (مثلاً فایل‌های SQL اولیه)
│   └── init.sql                    # فایل‌های SQL اولیه برای پایگاه داده
├── .env                            # فایل متغیرهای محیطی برای Docker Compose
└── docker-compose.yml              # فایل اصلی Docker Compose

برای شروع، یک دایرکتوری به نام lemp-stack ایجاد کرده و وارد آن شوید:


mkdir lemp-stack
cd lemp-stack

در ادامه، تمام فایل‌ها و دایرکتوری‌های مورد نیاز را درون lemp-stack ایجاد خواهیم کرد.

اجزای پشته LEMP و نحوه Dockerize کردن آنها

در این بخش، به بررسی دقیق هر یک از اجزای پشته LEMP می‌پردازیم و نحوه کانتینرسازی و پیکربندی آن‌ها را با جزئیات آموزش می‌دهیم.

Nginx: سرور وب پرسرعت

Nginx مسئول دریافت درخواست‌های HTTP از کاربران و هدایت آن‌ها به سرویس PHP-FPM است. ما از یک ایمیج رسمی Nginx استفاده می‌کنیم و فایل پیکربندی سفارشی خود را به آن اضافه خواهیم کرد.

ایجاد دایرکتوری و فایل پیکربندی Nginx

ابتدا دایرکتوری nginx را ایجاد کنید:


mkdir nginx

سپس، فایل default.conf را در دایرکتوری nginx/ ایجاد کنید و محتوای زیر را در آن قرار دهید:


# lemp-stack/nginx/default.conf

server {
    listen 80;
    listen [::]:80;
    server_name localhost; # یا نام دامنه شما

    root /var/www/html/public; # مسیر ریشه برنامه PHP شما در داخل کانتینر

    index index.php index.html index.htm;

    # تنظیمات برای مدیریت درخواست‌ها و مسیریابی
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # تنظیمات برای پردازش فایل‌های PHP توسط PHP-FPM
    location ~ \.php$ {
        try_files $request_filename =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000; # 'php' نام سرویس PHP-FPM در docker-compose.yml است
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    # جلوگیری از دسترسی به فایل‌های .htaccess
    location ~ /\.ht {
        deny all;
    }

    # تنظیمات لاگ‌گیری Nginx
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log warn;
}

توضیح پیکربندی Nginx:

  • listen 80;: Nginx بر روی پورت 80 (HTTP) گوش می‌دهد.
  • root /var/www/html/public;: این خط مشخص می‌کند که فایل‌های وب سایت شما در کدام مسیر در داخل کانتینر Nginx قرار دارند. ما فرض می‌کنیم کدهای PHP شما در دایرکتوری app/public پروژه میزبان قرار دارند که به /var/www/html/public در داخل کانتینر Nginx (و PHP) متصل می‌شود.
  • location /: این بلاک برای مدیریت درخواست‌های عمومی است. try_files تلاش می‌کند تا فایل درخواستی را پیدا کند؛ اگر پیدا نشد، به مسیر /index.php با رشته کوئری مربوطه هدایت می‌کند (مفید برای فریم‌ورک‌هایی مانند Laravel یا Symfony).
  • location ~ \.php$: این بلاک به Nginx می‌گوید که چگونه فایل‌های .php را پردازش کند.
    • fastcgi_pass php:9000;: این خط کلیدی است. Nginx درخواست‌های PHP را به سرویس php (که نام سرویس ما در docker-compose.yml خواهد بود) در پورت 9000 (پورت پیش‌فرض PHP-FPM) ارسال می‌کند.
    • include fastcgi_params; و fastcgi_param SCRIPT_FILENAME ...: اینها پارامترهای لازم را برای PHP-FPM فراهم می‌کنند تا بتواند اسکریپت PHP صحیح را شناسایی و اجرا کند.

PHP-FPM: مفسر قدرتمند PHP

PHP-FPM یک پیاده‌سازی جایگزین و پیشرفته‌تر از FastCGI برای PHP است که به PHP اجازه می‌دهد تا به عنوان یک فرآیند جداگانه اجرا شود و از طریق سوکت با Nginx ارتباط برقرار کند. این روش کارایی بسیار بالاتری نسبت به مدول‌های PHP در سرورهای وب سنتی دارد.

ایجاد دایرکتوری و Dockerfile PHP

دایرکتوری php را ایجاد کنید:


mkdir php

سپس، فایل Dockerfile را در دایرکتوری php/ ایجاد کنید و محتوای زیر را در آن قرار دهید:


# lemp-stack/php/Dockerfile

# استفاده از ایمیج رسمی PHP-FPM با Alpine Linux برای حجم کمتر
FROM php:8.2-fpm-alpine

# بروزرسانی و نصب وابستگی‌ها و اکستنشن‌های PHP
# --no-cache برای جلوگیری از ذخیره پکیج‌های دانلود شده در ایمیج نهایی
RUN apk add --no-cache \
    curl \
    mysql-client \
    git \
    unzip \
    libzip-dev \
    libpng-dev \
    jpeg-dev \
    libwebp-dev \
    imagemagick-dev \
    libxml2-dev \
    pcre-dev \
    && docker-php-ext-configure gd --with-jpeg --with-webp \
    && docker-php-ext-configure exif --enable-exif \
    && docker-php-ext-install -j$(nproc) pdo_mysql opcache gd exif pcntl zip soap dom xmlreader xmlwriter mbstring \
    && docker-php-ext-enable opcache \
    # حذف وابستگی‌های توسعه پس از نصب اکستنشن‌ها برای کاهش حجم ایمیج
    && apk del libzip-dev libpng-dev jpeg-dev libwebp-dev imagemagick-dev libxml2-dev pcre-dev

# نصب Composer (مدیر بسته برای PHP)
# استفاده از ایمیج جداگانه Composer برای کپی کردن اجرایی آن
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

# تنظیم دایرکتوری کاری پیش‌فرض
WORKDIR /var/www/html

# اکسپوز کردن پورت PHP-FPM
EXPOSE 9000

# دستور پیش‌فرض برای اجرای PHP-FPM
CMD ["php-fpm"]

توضیح Dockerfile PHP:

  • FROM php:8.2-fpm-alpine: ما از یک ایمیج PHP 8.2 با PHP-FPM بر روی Alpine Linux استفاده می‌کنیم. Alpine به دلیل حجم بسیار کم و امنیت بالا، برای کانتینرها ایده‌آل است.
  • RUN apk add ...: این دستور پکیج‌های سیستمی مورد نیاز برای کامپایل و نصب اکستنشن‌های PHP را نصب می‌کند. --no-cache برای اطمینان از حذف کش پکیج‌ها پس از نصب است تا حجم ایمیج افزایش نیابد.
  • docker-php-ext-configure ... و docker-php-ext-install ...: این دستورات اکستنشن‌های PHP مورد نیاز مانند pdo_mysql (برای اتصال به پایگاه داده)، opcache (برای بهبود عملکرد)، gd (برای پردازش تصویر) و zip را نصب می‌کنند. -j$(nproc) از تمام هسته‌های پردازنده برای سرعت بخشیدن به کامپایل استفاده می‌کند.
  • apk del ...: پس از نصب اکستنشن‌ها، پکیج‌های توسعه (dev-dependencies) را حذف می‌کنیم تا حجم ایمیج نهایی به حداقل برسد.
  • COPY --from=composer:latest ...: Composer را از ایمیج رسمی آن کپی می‌کنیم. این یک روش توصیه شده برای نصب Composer در Dockerfile است که ایمیج نهایی را تمیز نگه می‌دارد.
  • WORKDIR /var/www/html: دایرکتوری کاری پیش‌فرض را در داخل کانتینر به /var/www/html تنظیم می‌کند. این دایرکتوری جایی است که کدهای برنامه PHP شما قرار خواهند گرفت.
  • EXPOSE 9000: این خط نشان می‌دهد که کانتینر بر روی پورت 9000 گوش می‌دهد، که پورت پیش‌فرض PHP-FPM است.
  • CMD ["php-fpm"]: دستور پیش‌فرض برای اجرای سرویس PHP-FPM هنگام شروع کانتینر است.

MariaDB: پایگاه داده رابطه‌ای سبک و قدرتمند

MariaDB یک پایگاه داده رابطه‌ای است که سازگاری بالایی با MySQL دارد و به دلیل عملکرد و ویژگی‌های خود محبوبیت زیادی کسب کرده است. ما از ایمیج رسمی MariaDB استفاده خواهیم کرد و پایداری داده‌ها را از طریق حجم‌های Docker تضمین می‌کنیم.

پایداری داده‌ها برای MariaDB

یکی از مهم‌ترین جنبه‌ها هنگام استفاده از پایگاه داده در Docker، اطمینان از پایداری داده‌هاست. اگر کانتینر MariaDB شما حذف شود و داده‌ها پایدار نباشند، تمام اطلاعات شما از بین می‌رود. برای حل این مشکل، از Docker Volumes استفاده می‌کنیم. Docker Volumes یک روش ترجیحی برای ذخیره‌سازی داده‌های کانتینر هستند که به صورت جداگانه از چرخه حیات کانتینر مدیریت می‌شوند. ما یک “named volume” برای MariaDB تعریف خواهیم کرد.

فایل‌های SQL اولیه (اختیاری)

اگر نیاز دارید که هنگام راه‌اندازی اولیه کانتینر پایگاه داده، اسکیمای اولیه یا داده‌های پیش‌فرض را به آن اضافه کنید، می‌توانید یک دایرکتوری mariadb ایجاد کنید و فایل‌های SQL را در آن قرار دهید. Docker به طور خودکار فایل‌های .sql در مسیر /docker-entrypoint-initdb.d/ داخل کانتینر MariaDB را در اولین راه‌اندازی اجرا می‌کند. ما این دایرکتوری را در پروژه خود برای انعطاف‌پذیری بیشتر در نظر می‌گیریم:


mkdir mariadb
# می‌توانید فایل init.sql را در اینجا ایجاد کنید:
# touch mariadb/init.sql

محتوای نمونه برای mariadb/init.sql:


-- lemp-stack/mariadb/init.sql

CREATE DATABASE IF NOT EXISTS mydatabase;
USE mydatabase;

CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO users (name, email) VALUES ('John Doe', 'john.doe@example.com');
INSERT INTO users (name, email) VALUES ('Jane Smith', 'jane.smith@example.com');

این فایل در اولین باری که کانتینر MariaDB ایجاد می‌شود، پایگاه داده mydatabase را ایجاد کرده و جدول users را به همراه دو رکورد نمونه پر می‌کند.

ساختار فایل docker-compose.yml

فایل docker-compose.yml قلب پروژه ماست. این فایل تمام سرویس‌ها (Nginx, PHP, MariaDB) را تعریف می‌کند، نحوه ارتباط آن‌ها با یکدیگر را مشخص می‌سازد و پیکربندی‌های لازم مانند پورت‌ها، ولوم‌ها و متغیرهای محیطی را تعیین می‌کند.

ایجاد فایل docker-compose.yml

فایل docker-compose.yml را در ریشه دایرکتوری lemp-stack/ ایجاد کنید و محتوای زیر را در آن قرار دهید:


# lemp-stack/docker-compose.yml

version: '3.8' # تعیین نسخه API Docker Compose

# تعریف سرویس‌های مختلف برنامه
services:
  nginx:
    image: nginx:latest # استفاده از آخرین ایمیج رسمی Nginx
    container_name: lemp_nginx # نام دلخواه برای کانتینر
    restart: always # اطمینان از راه‌اندازی مجدد کانتینر در صورت توقف ناخواسته
    ports:
      - "80:80" # مپ کردن پورت 80 هاست به پورت 80 کانتینر برای دسترسی از مرورگر
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro # مپ کردن فایل پیکربندی Nginx (فقط خواندنی)
      - ./app:/var/www/html # مپ کردن کدهای برنامه به داخل کانتینر Nginx
    depends_on:
      - php # Nginx قبل از PHP-FPM راه‌اندازی می‌شود (فقط ترتیب، نه وابستگی سخت)
    networks:
      - lemp_network # اتصال به شبکه سفارشی

  php:
    build:
      context: ./php # مسیر Dockerfile برای ساخت ایمیج PHP-FPM
      dockerfile: Dockerfile
    container_name: lemp_php # نام دلخواه برای کانتینر
    restart: always
    volumes:
      - ./app:/var/www/html # مپ کردن کدهای برنامه به داخل کانتینر PHP-FPM
      - ./php/php.ini:/usr/local/etc/php/php.ini # اختیاری: مپ کردن فایل php.ini سفارشی
    environment:
      # تنظیمات OPcache برای PHP
      PHP_INI_SCAN_DIR: "/usr/local/etc/php/conf.d" # برای اسکن فایل‌های پیکربندی اضافی
    networks:
      - lemp_network # اتصال به شبکه سفارشی

  mariadb:
    image: mariadb:10.8 # استفاده از ایمیج رسمی MariaDB نسخه 10.8
    container_name: lemp_mariadb # نام دلخواه برای کانتینر
    restart: always
    environment:
      # متغیرهای محیطی برای پیکربندی اولیه MariaDB (از فایل .env خوانده می‌شوند)
      MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MARIADB_DATABASE: ${DB_DATABASE}
      MARIADB_USER: ${DB_USER}
      MARIADB_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mariadb_data:/var/lib/mysql # ولوم نام‌گذاری شده برای پایداری داده‌های پایگاه داده
      - ./mariadb:/docker-entrypoint-initdb.d # اختیاری: فایل‌های SQL اولیه
    networks:
      - lemp_network # اتصال به شبکه سفارشی

# تعریف ولوم‌ها برای پایداری داده‌ها
volumes:
  mariadb_data: # ولوم نام‌گذاری شده برای داده‌های MariaDB

# تعریف شبکه‌های سفارشی
networks:
  lemp_network:
    driver: bridge # استفاده از درایور bridge برای شبکه داخلی

توضیح فایل docker-compose.yml:

  • version: '3.8': نسخه API Docker Compose را مشخص می‌کند. همیشه بهتر است از آخرین نسخه پایدار استفاده کنید.
  • services:: این بخش تمام سرویس‌های تشکیل‌دهنده برنامه شما را تعریف می‌کند.
  • سرویس Nginx:
    • image: nginx:latest: کانتینر Nginx را از ایمیج رسمی nginx:latest می‌سازد.
    • ports: - "80:80": پورت 80 سیستم میزبان را به پورت 80 کانتینر Nginx مپ می‌کند. این به شما اجازه می‌دهد تا از طریق مرورگر به آدرس http://localhost به وب‌سایت خود دسترسی پیدا کنید.
    • volumes:: این بخش برای مپ کردن فایل‌ها و دایرکتوری‌ها بین سیستم میزبان و کانتینر استفاده می‌شود.
      • ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro: فایل پیکربندی Nginx ما را از سیستم میزبان به مسیر صحیح در داخل کانتینر مپ می‌کند. :ro آن را به صورت فقط خواندنی (read-only) mount می‌کند.
      • ./app:/var/www/html: دایرکتوری app پروژه ما را به /var/www/html در داخل کانتینر مپ می‌کند. این همان مسیری است که Nginx برای سرویس‌دهی فایل‌ها به آن اشاره دارد.
    • depends_on: - php: به Docker Compose می‌گوید که سرویس php باید قبل از nginx شروع شود. این فقط یک ترتیب شروع است و تضمین نمی‌کند که سرویس PHP کاملاً آماده دریافت اتصال باشد.
  • سرویس PHP:
    • build: context: ./php dockerfile: Dockerfile: به Docker Compose می‌گوید که ایمیج PHP را از Dockerfile موجود در دایرکتوری ./php بسازد.
    • volumes: - ./app:/var/www/html: کدهای برنامه PHP ما را به داخل کانتینر PHP مپ می‌کند، تا PHP-FPM بتواند به فایل‌های برنامه دسترسی داشته باشد.
    • volumes: - ./php/php.ini:/usr/local/etc/php/php.ini: این خط اختیاری است و به شما اجازه می‌دهد تا یک فایل php.ini سفارشی را برای پیکربندی PHP خود در کانتینر استفاده کنید. اگر این فایل را ندارید یا به پیکربندی‌های پیش‌فرض راضی هستید، می‌توانید این خط را حذف کنید.
    • environment: PHP_INI_SCAN_DIR: "/usr/local/etc/php/conf.d": این یک تنظیم مهم برای PHP-FPM است که به آن می‌گوید علاوه بر php.ini اصلی، فایل‌های پیکربندی اضافی را در دایرکتوری conf.d نیز اسکن کند. این برای ماژول‌هایی مانند OPcache که ممکن است تنظیمات اختصاصی خود را در فایل‌های جداگانه داشته باشند، ضروری است.
  • سرویس MariaDB:
    • image: mariadb:10.8: کانتینر MariaDB را از ایمیج رسمی mariadb:10.8 می‌سازد.
    • environment:: این بخش متغیرهای محیطی را برای پیکربندی اولیه MariaDB تنظیم می‌کند. مقادیر واقعی این متغیرها از فایل .env خوانده می‌شوند (به بخش بعدی مراجعه کنید).
      • MARIADB_ROOT_PASSWORD: رمز عبور کاربر ریشه پایگاه داده.
      • MARIADB_DATABASE: نام پایگاه داده‌ای که در ابتدا ایجاد می‌شود.
      • MARIADB_USER: نام کاربری که برای دسترسی به MARIADB_DATABASE ایجاد می‌شود.
      • MARIADB_PASSWORD: رمز عبور برای MARIADB_USER.
    • volumes::
      • mariadb_data:/var/lib/mysql: این خط یک “named volume” به نام mariadb_data را به دایرکتوری پیش‌فرض ذخیره‌سازی داده‌های MariaDB در داخل کانتینر مپ می‌کند. این کار تضمین می‌کند که داده‌های پایگاه داده شما حتی پس از حذف کانتینر، پایدار باقی بمانند.
      • ./mariadb:/docker-entrypoint-initdb.d: این ولوم اختیاری فایل‌های SQL ما را به مسیر صحیح در کانتینر مپ می‌کند تا در اولین راه‌اندازی اجرا شوند.
  • volumes:: این بخش تمام ولوم‌های نام‌گذاری شده را تعریف می‌کند که می‌توانند توسط سرویس‌ها استفاده شوند. mariadb_data: ولوم مورد نیاز ما برای MariaDB را تعریف می‌کند.
  • networks:: این بخش شبکه‌های سفارشی را تعریف می‌کند.
    • lemp_network: driver: bridge: یک شبکه bridge به نام lemp_network ایجاد می‌کند. تمامی سرویس‌های متصل به این شبکه می‌توانند با استفاده از نام سرویس (مثلاً php یا mariadb) با یکدیگر ارتباط برقرار کنند. این ایزوله‌سازی شبکه را فراهم کرده و از تداخل با سایر کانتینرها جلوگیری می‌کند.

ایجاد فایل متغیرهای محیطی (.env)

برای حفظ امنیت و انعطاف‌پذیری، هرگز اطلاعات حساس مانند رمز عبورها را مستقیماً در فایل docker-compose.yml قرار ندهید. در عوض، از فایل .env استفاده کنید. Docker Compose به طور خودکار این فایل را بارگذاری می‌کند و متغیرهای آن را در سرویس‌ها در دسترس قرار می‌دهد.

فایل .env را در ریشه دایرکتوری lemp-stack/ ایجاد کنید:


# lemp-stack/.env

# تنظیمات پایگاه داده MariaDB
DB_ROOT_PASSWORD=your_secure_root_password
DB_DATABASE=mydatabase_name
DB_USER=myuser
DB_PASSWORD=your_secure_password

مهم:

  • مقادیر را با اطلاعات واقعی و قوی جایگزین کنید.
  • فایل .env را هرگز در سیستم کنترل نسخه (مانند Git) قرار ندهید. به جای آن، یک فایل .env.example (مانند app/.env.example) بدون مقادیر حساس برای اطلاع سایر توسعه‌دهندگان از متغیرهای مورد نیاز ایجاد کنید.

گام‌به‌گام اجرا و تست پشته LEMP

اکنون که تمام فایل‌های پیکربندی و Dockerfile را ایجاد کرده‌ایم، زمان آن رسیده که پشته LEMP خود را بالا بیاوریم و عملکرد آن را تست کنیم.

1. ایجاد ساختار دایرکتوری و فایل‌های مورد نیاز

مطابق با ساختار پیشنهادی، مطمئن شوید که دایرکتوری‌ها و فایل‌های زیر را در پروژه lemp-stack/ خود ایجاد کرده‌اید:


lemp-stack/
├── nginx/
│   └── default.conf
├── php/
│   └── Dockerfile
├── app/
│   └── public/
│       └── index.php
├── mariadb/
│   └── init.sql
├── .env
└── docker-compose.yml

در صورتی که هنوز دایرکتوری app/public را ایجاد نکرده‌اید، این کار را انجام دهید:


mkdir -p app/public

2. ایجاد فایل nginx/default.conf

محتوای ذکر شده در بخش Nginx را در این فایل کپی کنید.

3. ایجاد فایل php/Dockerfile

محتوای ذکر شده در بخش PHP-FPM را در این فایل کپی کنید.

4. ایجاد فایل app/public/index.php

برای تست عملکرد PHP و اتصال به پایگاه داده، یک فایل index.php در مسیر app/public/ ایجاد کنید:


<!-- lemp-stack/app/public/index.php -->

<!DOCTYPE html>
<html lang="fa">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>تست پشته LEMP با Docker Compose</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; margin: 20px; background-color: #f4f4f4; color: #333; }
        .container { max-width: 800px; margin: auto; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
        h1, h2 { color: #0056b3; }
        p { margin-bottom: 10px; }
        .success { color: green; font-weight: bold; }
        .error { color: red; font-weight: bold; }
        pre { background: #eee; padding: 15px; border-radius: 5px; overflow-x: auto; }
    </style>
</head>
<body>
    <div class="container">
        <h1>پشته LEMP با Docker Compose با موفقیت اجرا شد!</h1<
        <p>نسخه PHP: <strong><?php echo phpversion(); ?></strong></p>

        <h2>تست اتصال به پایگاه داده MariaDB</h2>
        <?php
        $host = 'mariadb'; // نام سرویس MariaDB در docker-compose.yml
        $db   = getenv('DB_DATABASE');
        $user = getenv('DB_USER');
        $pass = getenv('DB_PASSWORD');
        $charset = 'utf8mb4';

        $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
        $options = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ];

        try {
            $pdo = new PDO($dsn, $user, $pass, $options);
            echo '<p class="success">با موفقیت به پایگاه داده MariaDB متصل شدید!</p>';

            // نمایش اطلاعات کاربران (در صورت وجود جدول users و اطلاعات در mariadb/init.sql)
            echo '<h3>نمونه کاربران:</h3>';
            $stmt = $pdo->query('SELECT id, name, email FROM users');
            echo '<ul>';
            while ($row = $stmt->fetch()) {
                echo '<li>' . htmlspecialchars($row['name']) . ' (' . htmlspecialchars($row['email']) . ')</li>';
            }
            echo '</ul>';

        } catch (\PDOException $e) {
            echo '<p class="error">خطا در اتصال به پایگاه داده MariaDB: <strong>' . htmlspecialchars($e->getMessage()) . '</strong></p>';
        }
        ?>

        <h2>اطلاعات PHP (phpinfo())</h2>
        <?php
        // نمایش اطلاعات کامل PHP
        // phpinfo();
        // برای امنیت در محیط تولید، phpinfo() را غیرفعال کنید.
        // برای دیدن آن، خط بالا را کامنت‌گذاری کنید و صفحه را رفرش کنید.
        ?>
    </div>
</body>
</html>

5. ایجاد فایل mariadb/init.sql (اختیاری)

محتوای ذکر شده در بخش MariaDB را در این فایل کپی کنید.

6. ایجاد فایل .env

محتوای ذکر شده در بخش `.env` را در این فایل کپی کنید و حتماً رمز عبورها و نام پایگاه داده را با مقادیر مورد نظر خود جایگزین کنید.

7. ایجاد فایل docker-compose.yml

محتوای ذکر شده در بخش docker-compose.yml را در این فایل کپی کنید.

8. اجرا کردن پشته LEMP

پس از ایجاد تمام فایل‌های بالا، به دایرکتوری lemp-stack/ در ترمینال خود بروید و دستور زیر را اجرا کنید:


docker-compose up -d --build
  • docker-compose up: این دستور کانتینرها را بر اساس پیکربندی موجود در docker-compose.yml ایجاد و اجرا می‌کند.
  • -d: (detached mode) کانتینرها را در پس‌زمینه اجرا می‌کند تا ترمینال شما آزاد شود.
  • --build: به Docker Compose می‌گوید که ایمیج‌های مورد نیاز را (در مورد PHP) قبل از راه‌اندازی سرویس‌ها، دوباره بسازد. این کار اطمینان می‌دهد که هر تغییری در Dockerfile PHP شما اعمال شده است.

این فرآیند ممکن است کمی طول بکشد، به خصوص در اولین بار که ایمیج‌ها دانلود و ساخته می‌شوند.

9. تایید اجرا

برای اطمینان از اینکه همه سرویس‌ها با موفقیت بالا آمده‌اند و در حال اجرا هستند، دستور زیر را اجرا کنید:


docker-compose ps

خروجی باید شبیه به این باشد، با وضعیت Up برای هر سه سرویس:


      Name                     Command               State           Ports
----------------------------------------------------------------------------------
lemp_mariadb        docker-entrypoint.sh mysqld      Up      3306/tcp
lemp_nginx          /docker-entrypoint.sh ngin ...   Up      0.0.0.0:80->80/tcp
lemp_php            docker-php-entrypoint php-fpm    Up      9000/tcp

10. بازدید از مرورگر

مرورگر وب خود را باز کنید و به آدرس http://localhost مراجعه کنید. شما باید صفحه “LEMP Stack is Running!” را ببینید که نسخه PHP و وضعیت اتصال به پایگاه داده MariaDB را نشان می‌دهد. اگر همه چیز درست باشد، پیام “با موفقیت به پایگاه داده MariaDB متصل شدید!” و لیست کاربران نمونه را خواهید دید.

11. توقف و حذف پشته

هنگامی که کار شما با پشته LEMP به پایان رسید، می‌توانید آن را به راحتی متوقف و حذف کنید:

  • برای توقف کانتینرها (بدون حذف):
  • 
    docker-compose stop
        
  • برای توقف و حذف کانتینرها و شبکه‌های مرتبط:
  • 
    docker-compose down
        
  • برای توقف و حذف کانتینرها، شبکه‌ها و همچنین ولوم‌های نام‌گذاری شده (مراقب باشید، این کار داده‌های پایگاه داده شما را نیز حذف می‌کند!):
  • 
    docker-compose down -v
        

در محیط‌های توسعه، docker-compose down -v معمولاً برای شروع دوباره از یک وضعیت تمیز مفید است. اما در محیط‌های تولید یا زمانی که نمی‌خواهید داده‌های پایگاه داده خود را از دست بدهید، فقط از docker-compose down استفاده کنید و ولوم mariadb_data را دست‌نخورده باقی بگذارید.

بهینه‌سازی‌ها و نکات پیشرفته

پس از راه‌اندازی موفقیت‌آمیز پشته LEMP، می‌توانید با اعمال برخی بهینه‌سازی‌ها و استفاده از قابلیت‌های پیشرفته Docker Compose، محیط خود را بهبود بخشید.

مدیریت پایداری داده‌ها و بکاپ‌گیری

همانطور که قبلاً اشاره شد، استفاده از Named Volumes (مانند mariadb_data) بهترین روش برای اطمینان از پایداری داده‌هاست. این ولوم‌ها مستقل از کانتینرها هستند و می‌توانند به راحتی پشتیبان‌گیری و بازیابی شوند.

  • پشتیبان‌گیری از ولوم‌ها: می‌توانید با ایجاد یک کانتینر موقت، از محتویات یک ولوم پشتیبان بگیرید.
  • 
    docker run --rm --volumes-from lemp_mariadb -v $(pwd):/backup ubuntu tar cvf /backup/mariadb_backup.tar /var/lib/mysql
        

    این دستور یک فایل mariadb_backup.tar در دایرکتوری فعلی شما ایجاد می‌کند.

  • Bind Mounts vs. Named Volumes: Bind mounts برای مپ کردن کد برنامه و فایل‌های پیکربندی مفید هستند که تغییرات مکرر دارند. Named volumes برای داده‌های پایدار (مانند پایگاه داده) که نباید به صورت تصادفی حذف شوند و مدیریت آن‌ها توسط Docker بهینه است، ارجحیت دارند.

تنظیم متغیرهای محیطی و امنیت

  • استفاده از فایل .env: همانطور که دیدیم، .env برای مدیریت متغیرهای محیطی غیر حساس عالی است.
  • Docker Secrets: برای اطلاعات بسیار حساس (مانند رمز عبورهای تولید، کلیدهای API)، بهتر است از Docker Secrets استفاده کنید. Docker Secrets بخشی از Docker Swarm هستند و برای محیط‌های تولیدی توصیه می‌شوند. با این حال، Docker Compose در حالت Swarm نیز می‌تواند از آن‌ها استفاده کند. این یک روش امن‌تر برای مدیریت اطلاعات حساس در محیط تولید است.
  • حداقل دسترسی: همیشه به سرویس‌ها حداقل دسترسی‌های لازم را بدهید. به عنوان مثال، کاربر پایگاه داده برنامه شما نباید دسترسی root داشته باشد.
  • به‌روزرسانی ایمیج‌ها: ایمیج‌های Docker خود را به طور منظم به‌روزرسانی کنید تا از آخرین پچ‌های امنیتی بهره‌مند شوید.

مانیتورینگ و لاگینگ

مانیتورینگ و مشاهده لاگ‌ها برای عیب‌یابی و حفظ سلامت برنامه حیاتی هستند.

  • docker-compose logs: برای مشاهده لاگ‌های تمام سرویس‌ها یا یک سرویس خاص.
  • 
    docker-compose logs -f # مشاهده لاگ‌های تمام سرویس‌ها در زمان واقعی
    docker-compose logs -f nginx # مشاهده لاگ‌های Nginx در زمان واقعی
        
  • ابزارهای مانیتورینگ: می‌توانید کانتینرهای مانیتورینگ مانند Prometheus و Grafana را به پشته Docker Compose خود اضافه کنید تا معیارهای عملکردی (CPU, RAM, Disk I/O) را جمع‌آوری و بصری‌سازی کنید.

بهینه‌سازی کارایی و عملکرد

  • PHP-FPM:
    • OPcache: مطمئن شوید که OPcache فعال است (همانطور که در Dockerfile ما فعال شد). این کار به طور قابل توجهی عملکرد PHP را با ذخیره کردن کد کامپایل شده PHP بهبود می‌بخشد.
    • تنظیمات Pool: فایل www.conf در /usr/local/etc/php-fpm.d/ را پیکربندی کنید. پارامترهایی مانند pm.max_children، pm.start_servers، pm.min_spare_servers و pm.max_spare_servers را بر اساس منابع سرور و بار کاری خود تنظیم کنید.
  • Nginx:
    • Worker Processes: در فایل nginx.conf (اگر آن را به صورت سفارشی مپ می‌کنید)، worker_processes را بر اساس تعداد هسته‌های CPU خود تنظیم کنید.
    • Caching: برای فایل‌های استاتیک، هدرهای caching مناسب را تنظیم کنید تا مرورگرها آن‌ها را کش کنند.
    • Gzip Compression: فشرده‌سازی Gzip را فعال کنید تا حجم داده‌های ارسالی کاهش یابد.
  • MariaDB:
    • Piknik: فایل my.cnf را برای MariaDB تنظیم کنید. پارامترهایی مانند innodb_buffer_pool_size، key_buffer_size و query_cache_size نقش مهمی در عملکرد پایگاه داده دارند.
    • Indexing: اطمینان حاصل کنید که ایندکس‌های مناسبی روی ستون‌های پرکاربرد جداول خود دارید.
  • Optimized Docker Images: همیشه از ایمیج‌های پایه کوچک‌تر (مانند Alpine) استفاده کنید و در Dockerfile خود مراحل Build Cache را بهینه کنید.

یکپارچه‌سازی با CI/CD

یکی از بزرگترین مزایای Docker Compose، قابلیت استفاده آسان آن در پایپ‌لاین‌های CI/CD است. می‌توانید:

  • از Docker Compose برای راه‌اندازی یک محیط تست ایزوله در هر Build استفاده کنید.
  • ایمیج‌های Docker سفارشی خود را بسازید و آن‌ها را به Docker Registry (مانند Docker Hub یا GitLab Container Registry) پوش کنید.
  • از همین فایل docker-compose.yml (با تغییرات جزئی برای محیط تولید) برای استقرار برنامه خود در سرورهای تولید استفاده کنید.

اضافه کردن خدمات دیگر

مزیت دیگر Docker Compose این است که به راحتی می‌توانید سرویس‌های اضافی را به پشته خود اضافه کنید:

  • PhpMyAdmin: برای مدیریت گرافیکی پایگاه داده.
  • 
      phpmyadmin:
        image: phpmyadmin/phpmyadmin
        container_name: lemp_phpmyadmin
        ports:
          - "8080:80"
        environment:
          PMA_HOST: mariadb
          MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
        networks:
          - lemp_network
        depends_on:
          - mariadb
        
  • Redis: برای کشینگ یا صف‌های کاری (queues).
  • 
      redis:
        image: redis:alpine
        container_name: lemp_redis
        networks:
          - lemp_network
        
  • Mailhog: برای تست ایمیل در محیط توسعه.
  • 
      mailhog:
        image: mailhog/mailhog
        container_name: lemp_mailhog
        ports:
          - "1025:1025" # SMTP
          - "8025:8025" # Web UI
        networks:
          - lemp_network
        

    برای اضافه کردن این سرویس‌ها، فقط کافی است بلاک‌های مربوطه را به بخش services در docker-compose.yml خود اضافه کنید و سپس docker-compose up -d را اجرا کنید.

عیب‌یابی و مشکلات رایج

هنگام کار با Docker و Docker Compose، ممکن است با مشکلاتی روبرو شوید. در اینجا برخی از مشکلات رایج و راه‌حل‌های آن‌ها آورده شده است:

  • پورت‌ها در حال استفاده هستند (Port is already in use):
    • مشکل: هنگامی که docker-compose up را اجرا می‌کنید، خطایی مانند Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use دریافت می‌کنید.
    • علت: پورت مشخص شده (مثلاً 80) قبلاً توسط برنامه دیگری در سیستم میزبان شما (شاید یک سرور وب محلی دیگر یا یک کانتینر Docker دیگر) استفاده می‌شود.
    • راه‌حل:
      1. برنامه در حال استفاده از پورت را متوقف کنید.
      2. پورت کانتینر Nginx را در docker-compose.yml تغییر دهید (مثلاً "8080:80").
      3. با sudo lsof -i :80 (در لینوکس) یا netstat -ano | findstr :80 (در ویندوز) می‌توانید برنامه‌ای که از پورت استفاده می‌کند را پیدا کنید.
  • مشکلات شبکه و عدم ارتباط بین کانتینرها:
    • مشکل: سرویس‌ها نمی‌توانند با یکدیگر ارتباط برقرار کنند (مثلاً PHP نمی‌تواند به MariaDB متصل شود).
    • علت: نام سرویس اشتباه در پیکربندی (مثلاً در index.php یا default.conf) یا مشکل در شبکه Docker.
    • راه‌حل:
      1. مطمئن شوید که نام سرویس‌ها (مثلاً mariadb در فایل index.php) با نام سرویس‌ها در docker-compose.yml مطابقت دارد.
      2. با دستور docker network ls شبکه‌های Docker را بررسی کنید و مطمئن شوید که سرویس‌ها به یک شبکه مشترک متصل هستند (مانند lemp_network در مثال ما).
      3. با docker exec -it [container_name] ping [other_service_name] می‌توانید اتصال شبکه بین کانتینرها را تست کنید.
  • تنظیمات نادرست Nginx یا PHP-FPM:
    • مشکل: صفحات 404 یا 502 (Bad Gateway) دریافت می‌کنید.
    • علت: Nginx نمی‌تواند فایل‌های PHP را پیدا کند یا نمی‌تواند به PHP-FPM متصل شود.
    • راه‌حل:
      1. لاگ‌های Nginx (docker-compose logs -f nginx) و PHP (docker-compose logs -f php) را به دقت بررسی کنید.
      2. مسیر root در nginx/default.conf را بررسی کنید و مطمئن شوید که با مسیر کدهای برنامه در داخل کانتینر مطابقت دارد.
      3. اطمینان حاصل کنید که fastcgi_pass php:9000; در Nginx به نام سرویس و پورت صحیح PHP-FPM اشاره دارد.
      4. بررسی کنید که فایل‌های PHP (مانند index.php) در دایرکتوری app/public وجود دارند و ولوم ./app:/var/www/html به درستی مپ شده است.
  • خطاهای اتصال به پایگاه داده:
    • مشکل: PHP نمی‌تواند به MariaDB متصل شود.
    • علت: متغیرهای محیطی نادرست (نام کاربری، رمز عبور، نام پایگاه داده) یا سرویس MariaDB به درستی شروع نشده است.
    • راه‌حل:
      1. لاگ‌های MariaDB (docker-compose logs -f mariadb) را بررسی کنید.
      2. مطمئن شوید که مقادیر DB_DATABASE، DB_USER و DB_PASSWORD در فایل .env با مقادیر مورد استفاده در index.php و تنظیمات MariaDB در docker-compose.yml مطابقت دارند.
      3. با استفاده از docker exec -it lemp_mariadb bash وارد کانتینر MariaDB شوید و با دستور mysql -u root -p (با رمز عبور root) صحت پایگاه داده و کاربران را بررسی کنید.
  • تغییرات کد اعمال نمی‌شوند:
    • مشکل: فایل‌های کد PHP را تغییر می‌دهید، اما تغییرات در مرورگر اعمال نمی‌شوند.
    • علت: مشکل در مپ کردن ولوم یا کشینگ PHP.
    • راه‌حل:
      1. مطمئن شوید که ولوم ./app:/var/www/html به درستی در docker-compose.yml برای سرویس‌های Nginx و PHP مپ شده است.
      2. ممکن است OPcache فعال باشد و تغییرات را فوراً نشان ندهد. می‌توانید OPcache را موقتاً غیرفعال کنید یا opcache.revalidate_freq را به مقدار کمتر تنظیم کنید (در php.ini سفارشی خود).
      3. بعضی اوقات، نیاز به ری‌استارت کردن سرویس PHP است: docker-compose restart php.
  • فضای دیسک پر می‌شود:
    • مشکل: Docker حجم زیادی از فضای دیسک را اشغال می‌کند.
    • علت: ایمیج‌های قدیمی، کانتینرهای متوقف شده، ولوم‌های استفاده نشده.
    • راه‌حل:
      1. docker system prune: تمام کانتینرهای متوقف شده، شبکه‌های استفاده نشده، ایمیج‌های بلاتکلیف و کش build را حذف می‌کند.
      2. docker system prune -a: علاوه بر موارد بالا، تمام ایمیج‌ها و ولوم‌هایی که توسط هیچ کانتینری استفاده نمی‌شوند را نیز حذف می‌کند (با احتیاط استفاده شود).

همیشه بهترین راه برای عیب‌یابی، بررسی دقیق لاگ‌های سرویس‌های مربوطه است. Docker Compose ابزارهای قدرتمندی برای این کار فراهم می‌کند که با کمی تمرین می‌توانید به سرعت مشکلات را شناسایی و رفع کنید.

نتیجه‌گیری

در این آموزش جامع، ما به طور گام به گام نحوه راه‌اندازی یک پشته کامل LEMP را با استفاده از Docker Compose بررسی کردیم. از معرفی اجزای پشته و ابزارهای Docker گرفته تا ایجاد Dockerfile‌های سفارشی برای PHP، پیکربندی Nginx و پایگاه داده MariaDB، و در نهایت اسمبل کردن همه چیز در یک فایل docker-compose.yml، هر مرحله با دقت توضیح داده شد.

توانایی کانتینرسازی محیط توسعه و استقرار شما، مزایای بی‌شماری از جمله ایزوله‌سازی، قابلیت تکرارپذیری، پرتابل بودن و سهولت مدیریت را به ارمغان می‌آورد. با Docker Compose، شما قادر خواهید بود محیط‌های پیچیده را تنها با چند دستور ساده بالا بیاورید و پایین بکشید، و این یعنی صرفه‌جویی قابل توجه در زمان و کاهش خطاهای انسانی.

ما همچنین به نکات پیشرفته‌تری مانند مدیریت پایداری داده‌ها با ولوم‌ها، استفاده از متغیرهای محیطی برای امنیت، بهینه‌سازی عملکرد و یکپارچه‌سازی با پایپ‌لاین‌های CI/CD پرداختیم. اضافه کردن سرویس‌های دیگر مانند PhpMyAdmin و Redis نیز نشان داد که چگونه Docker Compose انعطاف‌پذیری بی‌نظیری را برای گسترش زیرساخت شما فراهم می‌کند.

اکنون شما ابزارها و دانش لازم برای راه‌اندازی یک پشته LEMP مدرن و کارآمد را در اختیار دارید. این رویکرد نه تنها فرایند توسعه شما را ساده می‌کند، بلکه یک بنیاد قوی و قابل اطمینان برای استقرار برنامه‌های وب شما در محیط‌های مختلف فراهم می‌سازد. از این پس، “در سیستم من کار می‌کند!” دیگر بهانه نخواهد بود، زیرا محیط شما همیشه و همه جا سازگار است.

امیدواریم این راهنما برای شما مفید بوده باشد. اکنون نوبت شماست که این مفاهیم را در پروژه‌های خود به کار ببرید و از قدرت Docker و Docker Compose نهایت استفاده را ببرید. با تمرین و تجربه، به سرعت در استفاده از این ابزارهای قدرتمند مسلط خواهید شد.

“تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”

قیمت اصلی 2.290.000 ریال بود.قیمت فعلی 1.590.000 ریال است.

"تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"

"با شرکت در این دوره جامع و کاربردی، به راحتی مهارت‌های برنامه‌نویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر می‌سازد تا به سرعت الگوریتم‌های پیچیده را درک کرده و اپلیکیشن‌های هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفه‌ای و امکان دانلود و تماشای آنلاین."

ویژگی‌های کلیدی:

بدون نیاز به تجربه قبلی برنامه‌نویسی

زیرنویس فارسی با ترجمه حرفه‌ای

۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان