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

نخستین پروژه‌ای که روی Docker منتقل کردیم، پیش از آن روی سه دستگاه مختلف سه رفتار متفاوت داشت. روی یکی PHP نسخه ۷٫۴ بود، روی دیگری ۸٫۱، و روی سرور آزمایشی نسخه‌ای که هیچ‌کس دقیقاً نمی‌دانست. پس از کانتینری شدن، همان پروژه روی هر سه دستگاه یکسان اجرا شد. این تجربه، دلیل اصلی پذیرش Docker در جریان کاری توسعه وردپرس است.

Docker چیست و چرا محیط توسعه وردپرس را دگرگون می‌کند؟

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

در محیط توسعه وردپرس، Docker چند مسئله دیرینه را حل می‌کند. نخستین مسئله، تفاوت پیکربندی بین دستگاه‌های تیم است. وقتی یک توسعه‌دهنده روی macOS کار می‌کند و دیگری روی Windows، ناسازگاری‌های جزئی در مسیر فایل‌ها، سطح دسترسی و نسخه PHP می‌تواند به باگ‌های غیرقابل تکرار منجر شود. Docker این تفاوت‌ها را حذف می‌کند چون همه اعضای تیم یک تصویر یکسان اجرا می‌کنند.

مسئله دوم، آلودگی سیستم میزبان است. نصب مستقیم MySQL، PHP، Nginx و ابزارهای جانبی روی سیستم‌عامل میزبان، با گذشت زمان سیستم را شلوغ و مدیریت آن را دشوار می‌کند. کانتینر، این وابستگی‌ها را از سیستم میزبان جدا می‌کند و امکان حذف کامل با یک دستور را فراهم می‌آورد.

مسئله سوم، همخوانی با محیط تولید است. بسیاری از خطاها فقط در محیط تولید ظاهر می‌شوند، چون نسخه PHP یا پیکربندی سرور با محیط توسعه تفاوت دارد. با Docker می‌توان تصویری ساخت که دقیقاً با محیط تولید همخوان باشد. مفهوم پایه Docker در نوشتار چرا Docker انقلابی در استقرار نرم‌افزار ایجاد کرد؟ نگاهی عمیق به چرایی و پیامدها با جزئیات بیشتری بررسی شده است.

مرور کلی مفهوم کانتینر در ویکی‌پدیا نیز چارچوب گسترده‌تری ارائه می‌دهد: Docker (software).

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

در سطح جریان کاری، Docker سه مزیت عملی ایجاد می‌کند. نخست، راه‌اندازی پروژه جدید در چند دقیقه با یک فایل پیکربندی انجام می‌شود. دوم، تیم می‌تواند محیط‌های مختلف را برای سناریوهای متفاوت تعریف کند — مثلاً یک محیط با PHP 7.4 برای تست سازگاری و یک محیط با PHP 8.2 برای توسعه اصلی. سوم، انتقال پروژه بین توسعه‌دهندگان یا بین دستگاه‌ها بدون هیچ تنظیم دستی انجام می‌شود.

کانتینر در برابر ماشین مجازی: تفاوت معماری

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

ویژگی کانتینر ماشین مجازی
هسته سیستم‌عامل مشترک با میزبان مستقل
حجم چند ده مگابایت چند گیگابایت
زمان راه‌اندازی چند ثانیه چند دقیقه
مصرف منابع کم زیاد
ایزولاسیون سطح پردازش سطح سخت‌افزار
سرعت فایل‌سیستم بالا در Linux کندتر در bind mount

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

نکته مهم در محیط توسعه وردپرس این است که کانتینر Linux روی سیستم‌عامل میزبان macOS یا Windows از یک لایه ماشین مجازی سبک — مانند Docker Desktop یا Colima — استفاده می‌کند. این یعنی در محیط‌های غیر Linux، هزینه عملکردی اضافه‌ای وجود دارد که در سیستم‌های Linux بومی نیست. مقایسه تفصیلی این دو رویکرد در نوشتار آموزش Docker با مثال‌های واقعی: از اولین Container تا استقرار در Production با مثال‌های عملی ارائه شده است.

چرا سرعت فایل‌سیستم در محیط توسعه وردپرس حیاتی است

وردپرس از صدها فایل PHP تشکیل شده که در هر بار بارگذاری صفحه خوانده می‌شوند. اگر کانتینر روی macOS یا Windows اجرا شود و فایل‌های پروژه از طریق bind mount با سیستم میزبان به اشتراک گذاشته شوند، سرعت خواندن این فایل‌ها می‌تواند به‌شکل چشمگیری کاهش یابد. راهکارهای مختلفی برای این مشکل وجود دارد که در بخش‌های بعدی بررسی می‌شوند.

اجزای اصلی یک محیط توسعه Docker برای وردپرس

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

۱. کانتینر وردپرس

این کانتینر شامل هسته وردپرس، فایل‌های پروژه و افزونه‌ها و قالب است. این کانتینر روی یک تصویر PHP ساخته می‌شود که شامل یک وب‌سرور داخلی مانند Apache یا PHP-FPM است.

۲. کانتینر دیتابیس

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

۳. کانتینر وب‌سرور (اختیاری)

در پیکربندی‌های حرفه‌ای، Nginx یا Apache به‌عنوان لایه وب‌سرور جداگانه اجرا می‌شود و درخواست‌ها را به کانتینر PHP-FPM هدایت می‌کند. این ساختار با محیط تولید نزدیک‌تر است.

۴. کانتینر ابزارهای جانبی

ابزارهایی مانند phpMyAdmin، MailHog برای شبیه‌سازی ایمیل، Redis برای کش، و WP-CLI می‌توانند به‌عنوان کانتینرهای جداگانه اضافه شوند.

کانتینر نقش تصویر پیشنهادی
WordPress اجرای کد وردپرس wordpress:php8.2-apache
Database ذخیره داده‌ها mysql:8.0
phpMyAdmin مدیریت دیتابیس phpmyadmin/phpmyadmin
Redis کش شیء پایدار redis:alpine
MailHog شبیه‌سازی SMTP mailhog/mailhog

docker-compose.yml: قلب پیکربندی محیط

فایل docker-compose.yml قلب هر محیط توسعه Docker است. این فایل، همه سرویس‌ها، شبکه‌ها و Volumeها را در یک ساختار واحد تعریف می‌کند.

ساختار پایه

version: '3.8'

services:
  wordpress:
    image: wordpress:php8.2-apache
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: wp_pass
      WORDPRESS_DB_NAME: wp_dev
    volumes:
      - ./wp-content:/var/www/html/wp-content
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    depends_on:
      - db

  db:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: wp_dev
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_pass
      MYSQL_ROOT_PASSWORD: root_pass
    volumes:
      - db_data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8081:80"
    environment:
      PMA_HOST: db
      PMA_USER: wp_user
      PMA_PASSWORD: wp_pass
    depends_on:
      - db

volumes:
  db_data:

هر بخش این فایل معنا و کاربرد مشخصی دارد. بخش services کانتینرهای اصلی را تعریف می‌کند. بخش ports نگاشت پورت بین میزبان و کانتینر را مشخص می‌کند. بخش volumes داده‌های پایدار و فایل‌های پروژه را متصل می‌کند. بخش depends_on ترتیب راه‌اندازی را تعیین می‌کند.

مدیریت متغیرهای محیطی

برای پروژه‌های تیمی، نگه‌داشتن رمز عبور در فایل docker-compose.yml یک رویه نادرست است. می‌توان از فایل .env استفاده کرد:

WORDPRESS_DB_USER=wp_user
WORDPRESS_DB_PASSWORD=wp_pass
MYSQL_ROOT_PASSWORD=root_pass

سپس در فایل Compose به شکل زیر ارجاع داده می‌شود:

environment:
  WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
  WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}

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

فایل docker-compose.yml یک سند زنده است؛ هر تغییری در آن باید همزمان در مستندات تیم ثبت شود، وگرنه در چند هفته به یک قطعه کد مرموز تبدیل می‌شود.

راه‌اندازی گام‌به‌گام محیط توسعه وردپرس

این بخش یک مسیر عملی از نصب Docker تا اجرای نخستین سایت وردپرسی را ارائه می‌کند.

گام نخست: نصب Docker

روی macOS و Windows، Docker Desktop ساده‌ترین گزینه است. روی Linux، نصب بسته docker-ce و docker-compose-plugin از مخزن رسمی توصیه می‌شود.

گام دوم: ساخت ساختار پوشه پروژه

mkdir wp-docker-dev
cd wp-docker-dev
mkdir wp-content
mkdir config

گام سوم: ساخت فایل docker-compose.yml

محتوای فایل را با نمونه ارائه‌شده در بخش قبل ایجاد کنید. تنظیم مقادیر رمز عبور بر اساس نیاز پروژه انجام می‌شود.

گام چهارم: راه‌اندازی کانتینرها

docker compose up -d

دستور بالا، همه سرویس‌ها را در حالت detached اجرا می‌کند. با دستور زیر می‌توان وضعیت کانتینرها را بررسی کرد:

docker compose ps

گام پنجم: نصب وردپرس

با مراجعه به آدرس http://localhost:8080، فرآیند نصب وردپرس آغاز می‌شود. اطلاعات دیتابیس باید مطابق با مقادیر فایل Compose وارد شود.

گام ششم: تنظیم فایل wp-config.php

فایل wp-config.php که وردپرس به‌طور خودکار ایجاد می‌کند، باید به پوشه پروژه منتقل شود تا در کنترل نسخه قرار گیرد. با این کار، راه‌اندازی مجدد در آینده بدون نیاز به نصب دوباره انجام می‌شود.

گام هفتم: بررسی لاگ کانتینرها

docker compose logs -f wordpress

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

گام هشتم: توقف و حذف محیط

docker compose down

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

docker compose down -v

این عملیات داده‌های دیتابیس را نیز حذف می‌کند و باید با اطمینان از وجود بکاپ انجام شود. راهبردهای بکاپ در نوشتار چگونه از سایت وردپرسی بکاپ بگیریم؟ ارائه شده است.

Volume و پایداری داده‌ها

Volume مکانیزم اصلی Docker برای ذخیره داده‌های پایدار است. بدون Volume، با حذف کانتینر، همه داده‌ها از بین می‌روند.

انواع Volume

  • Named Volume: توسط Docker مدیریت می‌شود و در مسیر مخصوص Docker ذخیره می‌گردد. مناسب برای داده‌های دیتابیس.
  • Bind Mount: یک پوشه از سیستم میزبان به کانتینر متصل می‌شود. مناسب برای کد پروژه که باید ویرایش زنده داشته باشد.
  • tmpfs Mount: در حافظه ذخیره می‌شود و با توقف کانتینر از بین می‌رود. مناسب برای داده‌های موقت.

مشکل سرعت Bind Mount روی macOS و Windows

در macOS و Windows، bind mount از یک لایه ماشین مجازی عبور می‌کند و سرعت خواندن/نوشتن فایل‌ها به‌شکل چشمگیری کاهش می‌یابد. این مسئله در پروژه‌های وردپرسی که صدها فایل PHP در هر بار بارگذاری صفحه خوانده می‌شوند، محسوس است. راهکارهای موجود:

  • استفاده از mutagen یا docker-sync برای همگام‌سازی فایل‌ها.
  • فعال‌سازی VirtioFS در Docker Desktop جدید.
  • انتقال فایل‌های هسته وردپرس به داخل کانتینر و bind mount فقط پوشه wp-content.
  • استفاده از NFS یا SSHFS برای پروژه‌های بزرگ.

ساختار توصیه‌شده برای پروژه وردپرس

volumes:
  - ./wp-content/themes/my-theme:/var/www/html/wp-content/themes/my-theme
  - ./wp-content/plugins/my-plugin:/var/www/html/wp-content/plugins/my-plugin
  - wp_core:/var/www/html
  - db_data:/var/lib/mysql

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

شبکه‌سازی میان کانتینرها

Docker به‌طور پیش‌فرض یک شبکه داخلی برای هر فایل Compose ایجاد می‌کند. کانتینرها می‌توانند با نام سرویس خود یکدیگر را پیدا کنند.

شبکه پیش‌فرض

در نمونه فایل Compose بالا، کانتینر وردپرس با نام db به کانتینر دیتابیس متصل می‌شود. این نام، همان نام سرویس در فایل Compose است و توسط DNS داخلی Docker ترجمه می‌شود.

شبکه‌های سفارشی

networks:
  wp_network:
    driver: bridge

services:
  wordpress:
    networks:
      - wp_network
  db:
    networks:
      - wp_network

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

دسترسی به سرویس از میزبان

برای دسترسی به یک سرویس از سیستم میزبان، از نگاشت پورت استفاده می‌شود. برای مثال، نگاشت 8080:80 یعنی پورت ۸۰ کانتینر روی پورت ۸۰۸۰ میزبان در دسترس است. این الگو در نوشتار توسعه وردپرس با محیط لوکال چگونه انجام می‌شود با جزئیات بیشتری بررسی شده است.

Xdebug و دیباگ گام‌به‌گام در Docker

یکی از مزیت‌های کلیدی Docker در محیط توسعه، امکان راه‌اندازی یکپارچه Xdebug است. پیکربندی Xdebug در Docker چند نکته خاص دارد.

نصب Xdebug در تصویر PHP

با ساخت یک Dockerfile سفارشی، Xdebug در تصویر نصب می‌شود:

FROM wordpress:php8.2-apache

RUN pecl install xdebug 
    && docker-php-ext-enable xdebug

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

پیکربندی xdebug.ini

zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.idekey=VSCODE

مقدار host.docker.internal در Docker Desktop به آدرس میزبان اشاره می‌کند. در Linux، این مقدار باید آدرس IP میزبان در شبکه Docker باشد.

پیکربندی IDE

در VS Code، فایل launch.json باید پورت ۹۰۰۳ و pathMappings مناسب داشته باشد:

{
  "name": "Listen for Xdebug",
  "type": "php",
  "request": "launch",
  "port": 9003,
  "pathMappings": {
    "/var/www/html": "${workspaceFolder}"
  }
}

مسیر /var/www/html باید با مسیر داخل کانتینر همخوان باشد. اگر ساختار متفاوتی استفاده شود، Breakpoint کار نمی‌کند. مفاهیم پایه دیباگ گام‌به‌گام در نوشتار Step Debugging در وردپرس چطور انجام می‌شود؟ ارائه شده است.

مشکلات رایج در اتصال Xdebug

  • عدم دسترسی به میزبان: در Linux، host.docker.internal به‌طور پیش‌فرض وجود ندارد و باید با extra_hosts تعریف شود.
  • پورت بسته: فایروال میزبان باید پورت ۹۰۰۳ را باز نگه دارد.
  • pathMappings اشتباه: بدون تطابق مسیر، Breakpoint فعال نمی‌شود.
  • حالت Xdebug اشتباه: مقدار xdebug.mode باید حداقل شامل debug باشد.

WP-CLI در محیط کانتینری

WP-CLI ابزار خط فرمان وردپرس است که در محیط Docker دو کاربرد دارد: اجرای دستورات مدیریتی و اتوماسیون فرآیندهای تکراری.

اجرای WP-CLI از طریق کانتینر

docker compose exec wordpress wp plugin list

این دستور، WP-CLI را داخل کانتینر وردپرس اجرا می‌کند. برای دستوراتی که به دیتابیس نیاز دارند، باید مطمئن شوید که کانتینر دیتابیس فعال است.

نصب وردپرس با WP-CLI

docker compose exec wordpress wp core install 
  --url=http://localhost:8080 
  --title="Dev Site" 
  --admin_user=admin 
  --admin_password=admin 
  --admin_email=admin@example.com

این رویکرد، راه‌اندازی وردپرس را در چند ثانیه انجام می‌دهد و امکان اتوماسیون کامل فرآیند راه‌اندازی را فراهم می‌کند.

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

docker compose exec wordpress wp plugin install woocommerce --activate
docker compose exec wordpress wp theme install astra --activate

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

چند محیط توسعه موازی روی یک دستگاه

در پروژه‌های حرفه‌ای، اغلب نیاز به اجرای چند محیط موازی وجود دارد. مثلاً یک محیط برای توسعه، یک محیط برای تست سازگاری با PHP 7.4، و یک محیط برای تست با PHP 8.2.

راهکار نخست: چند فایل Compose

docker compose -f docker-compose.yml -f docker-compose.php74.yml up -d

این رویکرد، پیکربندی پایه را با یک override ترکیب می‌کند. فایل override فقط بخش‌های متفاوت را تعریف می‌کند.

راهکار دوم: استفاده از پورت‌های متفاوت

هر محیط با نام پروژه متفاوت و پورت متفاوت راه‌اندازی می‌شود:

COMPOSE_PROJECT_NAME=wp_dev_74 docker compose up -d

این روش، ایزولاسیون کامل بین محیط‌ها را تضمین می‌کند.

راهکار سوم: سرویس‌های مشترک

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

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

تصاویر Docker می‌توانند با گذشت زمان حجم قابل توجهی اشغال کنند. مدیریت صحیح آن‌ها بخشی از رویه حرفه‌ای است.

لایه‌بندی صحیح در Dockerfile

هر دستور RUN در Dockerfile یک لایه ایجاد می‌کند. ترکیب دستورهای مرتبط در یک RUN، تعداد لایه‌ها و حجم را کاهش می‌دهد:

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      git \
      unzip \
      libzip-dev \
    && docker-php-ext-install zip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

استفاده از تصاویر Alpine

تصاویر Alpine Linux با حجم پایین، گزینه مناسبی برای محیط‌های سبک هستند. برای مثال، mysql:8.0-alpine به‌جای mysql:8.0 حجم را چند برابر کاهش می‌دهد.

چند مرحله‌ای ساختن (Multi-stage Build)

در پروژه‌های پیچیده، می‌توان از multi-stage build استفاده کرد تا فقط فایل‌های ضروری به تصویر نهایی منتقل شوند:

FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci && npm run build

FROM wordpress:php8.2-apache
COPY --from=builder /app/dist /var/www/html/wp-content/themes/my-theme/assets

پاک‌سازی دوره‌ای

docker system prune -a --volumes

این دستور، تصاویر، کانتینرها، شبکه‌ها و Volumeهای بی‌استفاده را حذف می‌کند. باید با احتیاط اجرا شود، چون داده‌های Volume را نیز پاک می‌کند.

نگهداری تصاویر در Registry محلی

در تیم‌های بزرگ، نگهداری تصاویر در یک Registry محلی مانند Harbor یا Nexus، زمان دانلود و پهنای باند را کاهش می‌دهد. این رویکرد در نوشتار آموزش Git از صفر در چارچوب کلی مدیریت پروژه توسعه بحث شده است.

از Docker محلی تا استقرار در تولید

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

تفاوت‌های کلیدی محیط توسعه و تولید

ویژگی محیط توسعه محیط تولید
bind mount کد بله، برای ویرایش زنده خیر، کد داخل تصویر
Xdebug فعال غیرفعال
WP_DEBUG روی true روی false
کش غیرفعال برای توسعه چندلایه فعال
نسخه PHP حداقل نسخه پشتیبانی‌شده آخرین نسخه پایدار
ابزارهای جانبی phpMyAdmin، MailHog پایش، لاگ

الگوی ساخت تصویر تولید

FROM wordpress:php8.2-fpm-alpine

RUN apk add --no-cache \
    nginx \
    supervisor

COPY wp-content /var/www/html/wp-content
COPY config/nginx.conf /etc/nginx/nginx.conf

ENV WORDPRESS_DEBUG false
ENV WORDPRESS_CONFIG_EXTRA "define('WP_DEBUG', false);"

EXPOSE 80

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

انتقال داده‌های محیط توسعه به تولید

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

استقرار چندکانتینری در تولید

در محیط‌های تولید جدی، از ابزارهای ارکستراسیون مانند Kubernetes یا Docker Swarm استفاده می‌شود. این ابزارها مدیریت بار، بازیابی خودکار و مقیاس‌پذیری افقی را فراهم می‌کنند. مقایسه این دو ابزار در نوشتار Docker یا Kubernetes؟ کدام را برای پروژه انتخاب کنیم؟ ارائه شده است.

ملاحظات امنیتی در محیط Docker

محیط Docker، اگرچه ایزوله است، اما در برابر تهدیدات امنیتی مصون نیست. رعایت چند اصل ضروری است.

عدم اجرای کانتینر با کاربر root

در Dockerfile، باید یک کاربر غیر root ایجاد و کانتینر با آن اجرا شود:

RUN useradd -m -u 1000 wpuser
USER wpuser

محدودسازی منابع

services:
  wordpress:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M

پرهیز از mount پوشه‌های حساس

هرگز پوشه /، /etc یا /var/run/docker.sock را به کانتینر متصل نکنید. اتصال سوکت Docker به کانتینر، معادل دادن دسترسی کامل به میزبان است.

به‌روزرسانی منظم تصاویر

docker compose pull

تصاویر پایه مانند wordpress و mysql به‌طور منظم به‌روزرسانی امنیتی دریافت می‌کنند. اجرای دوره‌ای این دستور، امنیت محیط را حفظ می‌کند.

محدودسازی شبکه

در محیط‌های تیمی، دیتابیس باید فقط در شبکه داخلی Docker در دسترس باشد و از بیرون قابل دسترسی نباشد. حذف نگاشت پورت ۳۳۰۶ به میزبان، این ایزولاسیون را تضمین می‌کند.

اصول امنیت محیط توسعه، مکمل اصول کلی امنیت وب است. مرور این اصول در نوشتار بهترین روش‌های امنیت وب کدامند؟ توصیه می‌شود.

اشتباهات رایج در استفاده از Docker برای وردپرس

تجربه در پروژه‌های متعدد نشان می‌دهد برخی اشتباهات به‌طور مکرر تکرار می‌شوند:

  • نادیده گرفتن سرعت bind mount: روی macOS و Windows، اتصال کل پروژه به میزبان، سرعت را نابود می‌کند.
  • نگه‌داشتن داده در کانتینر بدون Volume: با حذف کانتینر، همه داده‌ها از بین می‌رود.
  • استفاده از تصویر latest: نسخه تصویر باید صریح مشخص شود تا رفتار در طول زمان تغییر نکند.
  • اجرای کانتینر با کاربر root: یک آسیب‌پذیری جدی در سطح میزبان.
  • نبود محدودیت منابع: یک کانتینر می‌تواند کل منابع میزبان را مصرف کند.
  • عدم مستندسازی فایل Compose: بدون کامنت و مستندات، فایل پس از چند ماه غیرقابل فهم می‌شود.
  • استفاده از رمز ثابت در فایل Compose: رمزها باید در فایل .env باشند.
  • نادیده گرفتن به‌روزرسانی تصاویر: تصاویر قدیمی می‌توانند آسیب‌پذیری امنیتی داشته باشند.
  • اجرای Xdebug روی همه درخواست‌ها: حالت start_with_request=yes در محیط‌های پرترافیک، عملکرد را کاهش می‌دهد.
  • نبود استراتژی برای حذف داده‌های Volume: Volumeهای باقی‌مانده، فضای دیسک را به‌مرور پر می‌کنند.

پرسش‌های پرتکرار درباره Docker و وردپرس

آیا Docker برای همه پروژه‌های وردپرس مناسب است؟

Docker برای پروژه‌های تیمی، پروژه‌هایی با نیاز به محیط‌های موازی و پروژه‌هایی که نیاز به همخوانی با محیط تولید دارند، مزیت چشمگیری دارد. برای پروژه‌های کوچک و تک‌نفره، ممکن است پیچیدگی اضافه محسوب شود، اما همچنان مزیت تکرارپذیری را فراهم می‌کند.

تفاوت Docker و Docker Compose چیست؟

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

آیا می‌توان از Docker برای پروژه ووکامرس استفاده کرد؟

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

چرا سرعت وردپرس در Docker روی macOS کند است؟

دلیل اصلی، هزینه bind mount روی macOS است. با انتقال هسته وردپرس به Volume داخلی Docker و bind mount فقط پوشه wp-content، سرعت به‌شکل محسوسی بهبود می‌یابد. فعال‌سازی VirtioFS در Docker Desktop جدید نیز تفاوت چشمگیری ایجاد می‌کند.

چگونه Xdebug را در Docker راه‌اندازی کنیم؟

با افزودن نصب Xdebug در Dockerfile، پیکربندی فایل xdebug.ini با xdebug.client_host=host.docker.internal، و تنظیم pathMappings در IDE. پورت پیش‌فرض ۹۰۰۳ باید در فایروال میزبان باز باشد.

آیا Docker جایگزین محیط لوکال سنتی است؟

در پروژه‌های جدی، Docker جایگزین رویکرد سنتی شده است، چون تکرارپذیری و ایزولاسیون را فراهم می‌کند. اما برای پروژه‌های آموزشی یا تمرینی کوچک، محیط لوکال سنتی همچنان می‌تواند کافی باشد.

آیا می‌توان چند پروژه Docker را به‌طور موازی اجرا کرد؟

بله. با تعریف نام پروژه متفاوت با COMPOSE_PROJECT_NAME و پورت‌های متفاوت، چند پروژه می‌توانند بدون تداخل اجرا شوند. هر پروژه شبکه و Volume مستقل خود را دارد.

چگونه داده‌های دیتابیس را از کانتینر استخراج کنیم؟

docker compose exec db mysqldump -u root -p wp_dev > backup.sql

این دستور، نسخه پشتیبان دیتابیس را در فایل محلی ذخیره می‌کند. برای بازیابی، از ابزار mysql با ورودی فایل استفاده می‌شود.

آیا Docker در محیط تولید نیز قابل استفاده است؟

بله، اما تفاوت‌های محیط تولید باید لحاظ شود: عدم bind mount، غیرفعال بودن Xdebug، فعال بودن کش چندلایه و استفاده از تصاویر بهینه‌شده. برای محیط‌های بزرگ، ابزارهای ارکستراسیون مانند Kubernetes توصیه می‌شود.

آیا استفاده از Docker باعث کاهش امنیت می‌شود؟

خیر، اگر اصول امنیتی رعایت شود. اجرای کانتینر با کاربر non-root، محدودسازی منابع، به‌روزرسانی منظم تصاویر و عدم اتصال سوکت Docker، محیط را امن می‌کند. در برخی سناریوها، ایزولاسیون Docker نسبت به نصب مستقیم روی میزبان، امنیت بیشتری فراهم می‌کند.

چگونه مصرف منابع Docker را کاهش دهیم؟

با محدودسازی منابع هر سرویس در فایل Compose، استفاده از تصاویر Alpine، پاک‌سازی دوره‌ای با docker system prune و حذف Volumeهای بی‌استفاده. در محیط‌های توسعه، غیرفعال کردن سرویس‌هایی که در لحظه نیاز نیستند، مصرف را کاهش می‌دهد.

آیا Docker بر سرعت توسعه تأثیر می‌گذارد؟

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

زیر پوست کانتینر: نگاه سطح پلتفرم

در سطح مهندسی پلتفرم، Docker یک لایه انتزاعی روی سازوکارهای هسته Linux است. کانتینر، یک پردازش معمولی است که با استفاده از namespaceها و cgroupها ایزوله می‌شود. این درک پایه، تفاوت‌های عملی مهمی را روشن می‌کند.

namespaceها شش نوع اصلی دارند: PID برای جداسازی دید پردازش‌ها، NET برای جداسازی شبکه، MNT برای جداسازی نقاط mount، UTS برای جداسازی نام میزبان، IPC برای جداسازی ارتباط بین‌پردازشی و USER برای جداسازی شناسه‌های کاربری. هرکدام از این namespaceها یک لایه ایزولاسیون مستقل ایجاد می‌کنند و از طریق فراخوانی سیستم clone با پرچم‌های مربوطه فعال می‌شوند.

cgroupها منابع را محدود می‌کنند. بخش deploy.resources.limits در فایل Compose، مستقیماً به تنظیمات cgroup ترجمه می‌شود. مفهوم cpu.shares در cgroup، وزن نسبی هر کانتینر در دسترسی به CPU را تعیین می‌کند؛ این یعنی اگر دو کانتینر با وزن ۵۱۲ و ۱۰۲۴ اجرا شوند، دومی دو برابر پردازنده دریافت می‌کند.

در لایه فایل‌سیستم، مفهوم OverlayFS نقش محوری دارد. Docker از OverlayFS برای ساخت لایه‌های تصویر استفاده می‌کند. هر دستور در Dockerfile یک لایه جدید می‌سازد و لایه‌های زیرین به‌صورت فقط‌خواندنی مشترک می‌مانند. این طراحی، حجم تصاویر را کاهش می‌دهد و زمان ساخت را سرعت می‌بخشد. مفهوم copy-on-write در این لایه، بهینه‌سازی مهمی است: فایل‌ها فقط زمانی که تغییر کنند، در لایه بالایی کپی می‌شوند.

در لایه شبکه، Docker از سه درایور اصلی استفاده می‌کند: bridge برای شبکه پیش‌فرض میزبان، host برای اشتراک مستقیم شبکه میزبان و overlay برای شبکه چند میزبان در Docker Swarm. انتخاب درایور درست، اثر مستقیم بر کارایی و ایزولاسیون دارد. در محیط توسعه، bridge گزینه پیش‌فرض و مناسب است.

در لایه پایداری داده، مفهوم Volume driver اهمیت دارد. Docker از درایورهای مختلفی مانند local، nfs، cifs و درایورهای سرویس‌های ابری پشتیبانی می‌کند. در محیط تولید که چند سرور وجود دارد، استفاده از درایور nfs یا مشابه، امکان اشتراک داده بین کانتینرها روی سرورهای مختلف را فراهم می‌کند.

در لایه پایش، مفهوم container observability شامل چهار ستون است: metric سطح کانتینر، لاگ stdout، trace درخواست و رویدادهای Docker daemon. ابزارهایی مانند cAdvisor، Prometheus و Loki این لایه‌ها را پوشش می‌دهند. برای محیط توسعه، ابزارهای سبک‌تری مانند docker stats و docker compose logs کافی است، اما در محیط‌های تیمی بزرگ، پایش حرفه‌ای ضروری می‌شود.

در لایه امنیت، مفهوم capability dropping ابزار قدرتمندی است. کانتینرها به‌طور پیش‌فرض مجموعه‌ای از capabilityهای Linux را دریافت می‌کنند. حذف capabilityهای غیرضروری مانند NET_RAW، SYS_ADMIN و MKNOD، سطح حمله را کاهش می‌دهد. این تنظیم از طریق cap_drop در فایل Compose انجام می‌شود.

در لایه زمان‌بندی، مفهوم orchestration scheduler در محیط‌های چندسروری وارد بازی می‌شود. Docker Swarm و Kubernetes هر دو زمان‌بندهایی دارند که توزیع کانتینرها روی گره‌های مختلف را مدیریت می‌کنند. الگوریتم‌های زمان‌بندی این ابزارها بر پایه معیارهایی مانند ظرفیت منابع، نزدیکی شبکه و سیاست‌های affinity عمل می‌کنند. نگاه کلی به این معماری در نوشتار آموزش Kubernetes برای مبتدیان: از مفاهیم پایه تا مدیریت کانتینرها در مقیاس ارائه شده است.

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

پایان‌بندی

Docker برای محیط توسعه وردپرس یک تغییر ساختاری در جریان کاری است، نه فقط یک ابزار کمکی. با کانتینری کردن پشته نرم‌افزاری، مسائل کلاسیک محیط توسعه مانند ناسازگاری نسخه، تفاوت رفتار بین دستگاه‌ها و آلودگی سیستم میزبان به‌طور بنیادی حل می‌شوند. اما Docker مسئولیت‌های جدیدی نیز به همراه دارد: نیاز به درک مفاهیم شبکه، Volume و امنیت کانتینر، و انتخاب آگاهانه بین رویکردهای مختلف. توسعه‌دهندگانی که این مفاهیم را درونی می‌کنند، محیطی قابل تکرار و مشترک برای تیم خود می‌سازند که سرعت توسعه و کیفیت تحویل را به‌شکل محسوسی بهبود می‌دهد. در پروژه‌های حرفه‌ای، Docker به یک مهارت پایه تبدیل شده است، نه یک گزینه لوکس.

اگر این مسیر را در یک پروژه واقعی طی کرده‌اید، برای ادامه گفتگو مفید است بدانم کدام بخش بیشترین زمان را از شما گرفته است: بهینه‌سازی سرعت فایل‌سیستم روی macOS، پیکربندی Xdebug در کانتینر، یا انتقال محیط توسعه به تولید. تجربه خود را در دیدگاه‌ها بنویسید؛ به‌ویژه اگر راه‌حل متفاوتی برای همان مشکل پیدا کرده‌اید که می‌تواند برای خواننده بعدی ارزشمند باشد.