You are currently viewing آموزش نصب وردپرس با Docker Compose – راهنمای گام به گام

آموزش نصب وردپرس با Docker Compose – راهنمای گام به گام


وردپرس به‌عنوان ابزار مدیریت محتوا (CMS) متن‌باز و رایگان به افرادی که قصد دارند وب‌سایت راه‌اندازی کنند، کمک می‌کند تا بتوانند وب‌سایت‌های خود را با استفاده از ابزارهای گرافیکی و بدون نیاز به دانش کدنویسی راه‌اندازی کنند. اجرای وردپرس معمولاً شامل نصب پشته LAMP (مخفف Linux, Apache, MySQL, PHP) یا LEMP (مخفف Linux, Nginx, MySQL, PHP) است که می‌تواند کاری زمان‌بر باشد. برای رفع این مشکل، می‌توانید از ابزارهایی مانند Docker Compose استفاده کنید.

در این مطلب از بلاگ پارس پک، قصد داریم تا نحوه نصب وردپرس چند‌کانتینری، شامل کانتینرهای MySQL به‌عنوان پایگاه داده و وب سرور Nginx و خود وردپرس و نیز نحوه دریافت گواهی SSL/TLS رایگان ازطریق Let’s Encrypt و نصب آن روی وردپرس را به شما آموزش دهیم.

پیش‌نیازها

برای اینکه بتوانید روند توضیح‌داده‌شده در این مطلب را گام‌به‌گام پیش ببرید، به پیش‌نیازهای زیر نیاز خواهید داشت:

  • سرور با سیستم‌عامل اوبونتو ورژن 20.04 به‌همراه کاربر غیر Root با دسترسی Sudo و فایروال فعال
  • Docker نصب‌شده روی سرور
  • Docker Compose نصب‌شده روی سرور
  • دامنه‌ای که مالکیت و مدیریت آن در‌اختیار خودتان باشد. در تمامی مثال‌های این آموزش، به‌جای دامنه از your_domain استفاده شده است. 
  • دو رکورد ثبت‌شده DNS به‌صورت your_domain و www.your_domain که هر دو به آدرس IP عمومی سرور شما اشاره می‌کنند.

هنگامی‌که این پیش‌نیازها را تأمین کردید، روند گام‌به‌گام نصب وردپرس با Docker Compose را می‌توانید دنبال کنید.

گام اول: تعریف پیکربندی وب سرور

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

mkdir wordpress

سپس با استفاده از دستور cd، به دایرکتوری ایجاد‌شده وارد شوید:

cd wordpress

حالا با استفاده از دستور زیر، دایرکتوری دیگری برای فایل پیکربندی ایجاد کنید:

mkdir nginx-conf

فایل را با استفاده از ویرایشگر باز کنید. در این مثال، ما از ویرایشگر nano برای این منظور استفاده کرده‌ایم:

nano nginx-conf/nginx.conf

در این فایل، باید یک بلوک سرور برای Name Server و داکیومنت روت و بلوک‌های لوکیشن (Location Block) را اضافه کنید. این موضوع امکان پردازش PHP و درخواست کلاینت گواهی Certbot و Request‌های مربوط به Asset‌های ثابت را فراهم خواهد کرد.

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

server {
        listen 80;
        listen (::):80;

        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ .php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* .(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

پس از آنکه کدهای عنوان‌شده را در فایل قرار دادید، فایل را ذخیره کنید و سپس آن را ببندید. درصورتی‌که از ویرایشگر متن Nano استفاده می‌کنید، این کار با استفاده از کلیدهای ترکیبی Ctrl+X و کلید Y و در‌نهایت فشردن Enter انجام خواهد شد.

گام دوم: تغییر متغیرهای محیطی (Environment Variables)

پایگاه داده و کانتینرهای برنامه وردپرس در زمان اجرا به دسترسی به متغیرهای محیطی نیاز دارند. این متغیرها به دو نوع حساس و غیرحساس تقسیم‌ می‌شوند. به‌عنوان نمونه، متغیری که برای رمزعبور Root پایگاه داده MySQL تنظیم می‌شود، جزو متغیرهای حساس است؛ اما درمقابل، خود نام پایگاه داده در دسته متغیرهای غیرحساس قرار خواهد گرفت. 

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

در دایرکتوری اصلی پروژه‌تان (احتمالاً مسیری شبیه به ~/wordpress باشد) فایلی با نام .env باز کنید:

nano .env

مقادیر محرمانه‌ای که قصد داریم در این فایل وارد کنیم، یک رمزعبور برای کاربر ریشه MySQL و یک نام کاربری و رمزعبوری است که وردپرس از آن برای دسترسی به پایگاه داده استفاده می‌کند. نام این متغیرها و مقادیر آن‌ها با استفاده از دستورهای زیر به فایل اضافه خواهند شد. به‌یاد بسپارید که شما باید مقادیر خود را در این فایل وارد کنید:

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

همان‌طور‌که می‌بینید، در این فایل رمزعبور کاربر ریشه MySQL و نام کاربری و رمزعبور دلخواه برای ورود به پایگاه داده تنظیم شده است. بعد از اینکه ویرایش فایل به‌اتمام رسید، آن را ببندید.

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

اگر قصد دارید برای کنترل نسخه از Git استفاده کنید، دایرکتوری مجازی خود را به‌عنوان ریپوزیتوری با git int مقداردهی اولیه کنید:

git init

برای ایجاد و باز‌کردن فایل .gitignore از دستور زیر استفاده کنید:

nano .gitignore

.env را به فایل اضافه کنید:

.env

هنگامی‌که کار ویرایش فایل به‌پایان رسید، آن را ذخیره کنید و ببندید. همان‌طور‌که قبلاً نیز توضیح دادیم، اضافه‌کردن .env به فایل dockerignore نیز اقدام احتیاطی مثبتی است. برای این منظور ابتدا باید این فایل را باز کنید:

nano .dockerignore

حالا جزء .env را به این فایل نیز اضافه کنید:

.env

در زیر این خط، می‌توانید فایل‌ها و دایرکتوری‌های مرتبط با توسعه برنامه خود را نیز اضافه کنید؛ البته این کار اختیاری است:

.env
.git
docker-compose.yml
.dockerignore

پس از پایان کار، فایل را ذخیره کنید و آن را ببندید. حالا می‌توانید سرویس‌های مدنظرتان را در docker-compose.yml تعریف کنید. این موضوع در قدم بعدی توضیح داده شده است.

داکر چیست و چگونه کار می‌کند؟ چه مزیت‌ها و معایبی دارد؟ چرا باید از داکر استفاده کنیم؟ در مقاله زیر بخوانید.

داکر چیست؟

گام سوم: تعریف سرویس‌ها با استفاده از Docker Compose

فایل docker-composer.yml حاوی سرویس‌هایی است که برای راه‌اندازی به آن‌ها نیاز خواهید داشت. در‌واقع، تعریف هر سرویس اطلاعاتی را درخصوص نحوه اجرای هر کانتینر مشخص خواهد کرد.

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

برای شروع ایجاد و باز‌کردن docker-compose.yml، از دستور زیر استفاده کنید:

nano docker-compose.yml

بعد از اینکه فایل را باز کردید، از دستور زیر برای تعریف نسخه فایل Compose و سرویس پایگاه داده استفاده کنید:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

سپس در خط بعدی تعریف سرویس db (دیتابیس)، تعریف سرویس برنامه وردپرس خود را با استفاده از کدهای زیر اضافه کنید:

...
  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

بعد از انجام این کار، نوبت به تعریف سرویس وب سرور Nginx می‌‌رسد. این کار با استفاده از کدهای زیر امکان‌پذیر است:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

در پایان نیز، باید تعریف سرویس Certbot را انجام دهید. در‌ادامه تعریف وب سرویس، کدهای زیر را اضافه کنید تا سرویس Certbot نیز تعریف شود:

certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email (email protected)_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

تا این قسمت، تمامی سرویس‌های موردنیاز خود را تعریف کرده‌اید. در‌ادامه، باید شبکه و Volume را تعریف کنید. این کار با استفاده از کدهای زیر انجام خواهد شد:

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

با‌توجه‌به توضیحاتی که تا این‌جای مطلب دادیم، فایل docker-compose.yml شما باید به‌صورت زیر درآمده باشد:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email (email protected)_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

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

گام چهارم: دریافت گواهینامه SSL

با استفاده از دستور docker-compose up، کانتینرهای خود را اجرا کنید. در این صورت، کانتینرها با همان ترتیبی که مشخص کرده‌اید، ایجاد و اجرا خواهند شد. با اضافه‌کردن فلگ -d، کانتینر db و wordpress و webserver در پس‌زمینه اجرا خواهند شد:

docker-compose up -d

در‌صورتی‌که سرویس‌ها به‌درستی ایجاد شده باشند، شما باید خروجی زیر را ببینید:

Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot   ... done

سپس با استفاده از دستور docker-compose ps، وضعیت سرویس‌های خود را بررسی کنید:

docker-compose ps

در خروجی این دستور، مشاهده خواهید کرد که سرویس‌های wordpress و db و webserver در وضعیت UP قرار دارند که یعنی این سرویس‌ها بالا هستند. همچنین در وضعیت کانتینر certbot، عبارت EXIT 0 را مشاهده خواهید کرد:

Output
  Name                 Command               State           Ports       
-------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                      
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp
webserver   nginx -g daemon off;             Up       0.0.0.0:80->80/tcp 
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp

اگر در خروجی db و webserver و wordpress، چیزی به‌غیر از Up و در خروجی certbot، چیزی به‌غیر از Exit 0 می‌بینید، یعنی احتمالاً باید گزارش‌های سرویس را با استفاده از دستور docker-compose logs مجدداً بررسی کنید:

docker-compose logs service_name

حالا می‌توانید با استفاده از docker-compose exec بررسی کنید که آیا گواهی‌های شما در کانتینر webserver نصب شده‌اند یا خیر:

docker-compose exec webserver ls -la /etc/letsencrypt/live

در‌صورتی‌که همه‌چیز با موفقیت انجام شده باشد، خروجی این دستور باید چیزی شبیه به این باشد:

Output
total 16
drwx------    3 root     root          4096 May 10 15:45 .
drwxr-xr-x    9 root     root          4096 May 10 15:45 ..
-rw-r--r--    1 root     root           740 May 10 15:45 README
drwxr-xr-x    2 root     root          4096 May 10 15:45 your_domain

حالا که از موفقیت‌آمیز‌بودن فرایند تا این مرحله مطمئن‌ شده‌اید، می‌توانید مجدداً سرویس certbot را ویرایش و فلگ –staging را حذف کنید. برای این منظور، docker-compose.yml را با استفاده از دستور زیر باز کنید:

nano docker-compose.yml

در این فایل، قسمتی که سرویس certbot در آن تعریف شده، پیدا و فلگ –staging را با –force-renewal جایگزین کنید. این فلگ به certbot می‌گوید که شما قصد دارید گواهی جدیدی برای همان دامنه درخواست بدهید. نمونه زیر این موضوع را نشان می‌دهد:

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email (email protected)_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...

حالا می‌توانید docker-compose را برای ایجاد مجدد کانتینر certbot اجرا کنید. با‌توجه‌به اینکه سرویس webserver در حال اجراست، با اضافه‌کردن –no-deps به دستور، به compose بگویید تا از راه‌اندازی این سرویس صرف‌نظر کند:

docker-compose up --force-recreate --no-deps certbot

در‌صورتی‌که خروجی شما به‌صورت زیر باشد، بدین‌معنی است که درخواستتان با موفقیت انجام شده است:

Output
Recreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for your_domain
certbot      | http-01 challenge for www.your_domain
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   
certbot      |    Donating to EFF:                    
certbot      | 
certbot exited with code 0

با در‌اختیار‌داشتن گواهی‌ها، شما می‌توانید پیکربندی Nginx را برای استفاده از گواهی SSL تغییر دهید. این موضوع در گام بعدی آموزش داده شده است.

برای آشنایی با آموزش کامل نصب SSL در وردپرس و ثبت سایت https در سرچ کنسول مقاله زیر را بخوانید.

نصب SSL در وردپرس

گام پنجم: تغییر پیکربندی وب سرور و تعریف سرویس

برای فعال‌کردن گواهی SSL در وب سرور Nginx، باید ری‌دایرکتی از پروتکل HTTP به HTTPS انجام دهید. علاوه‌بر‌این، باید محل گواهی SSL و کلیدهای گواهی را مشخص و درنهایت پارامترهای امنیتی را نیز در هِدِرها اضافه کنید.

با‌توجه‌به اینکه برای این کار باید سرویس webserver را مجدداً ایجاد کنید تا این موارد را به آن بیفزایید، در ابتدا باید سرویس را متوقف کنید. این کار با استفاده از دستور زیر انجام خواهد شد:

docker-compose stop webserver

قبل از اینکه فایل سرویس را تغییر دهید، پارامترهای امنیتی توصیه‌شده Nginx را با استفاده از Curl از Certbot دریافت کنید:

curl -sSLo nginx-conf/options-ssl-nginx.conf 

این دستور باعث می‌شود که این پارامترها در فایلی با نام options-ssl-nginx.conf و در دایرکتوری nginx-conf ذخیره شوند. در مرحله بعد، با استفاده از دستور زیر فایل پیکربندی Nginx را که قبلاً ایجاد کرده‌اید، حذف کنید:

rm nginx-conf/nginx.conf

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

nano nginx-conf/nginx.conf

کدهای زیر را به فایل اضافه کنید تا عملیات ری‌دایرکت از پروتکل HTTP به HTTPS و تنظیمات لازم برای استفاده از گواهی SSL نیز انجام شود. فراموش نکنید که به‌جای your_domain باید از نام دامنه خودتان استفاده کنید:

server {
        listen 80;
        listen (::):80;

        server_name your_domain www.your_domain;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^  permanent;
        }
}

server {
        listen 443 ssl http2;
        listen (::):443 ssl http2;
        server_name your_domain www.your_domain;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ .php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* .(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

حالا با دستور زیر، فایل docker-compose.yml را باز کنید:

nano docker-compose.yml

در قسمتی از فایل که سرویس وب سرور تعریف شده است، port mapping زیر را اضافه کنید:

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

بنابراین، نسخه کامل فایل docker-compose.yml شما باید به‌صورت زیر باشد:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email (email protected)_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

بعد از اینکه ویرایش فایل با موفقیت به‌اتمام رسید، تغییرات را ذخیره کنید و فایل را ببندید. سپس، سرویس webserver را مجدداً ایجاد کنید:

docker-compose up -d --force-recreate --no-deps webserver

درادامه، با استفاده از docker-compose ps، سرویس را مجدداً تست کنید:

docker-compose ps

خروجی این دستور باید نشان دهد که سرویس‌های wordpress و db و webserver در حال اجرا هستند:

Output
  Name                 Command               State                     Ports                  
----------------------------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                                           
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp                     
webserver   nginx -g daemon off;             Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp

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

هر آنچه باید درباره سیستم مدیریت محتوای وردپرس بدانید را در مقاله زیر بخوانید.

وردپرس چیست؟

گام ششم: نصب وردپرس با استفاده از رابط وب

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


در گام بعدی، زبانی که می‌خواهید وردپرس بر‌اساس آن نصب شود، انتخاب کنید:

زبان وردپرس را انتخاب کنید

بعد از انتخاب زبان و کلیک روی دکمه Continue، به صفحه اصلی نصب وردپرس هدایت خواهید شد. در این صفحه، باید نامی برای وب‌سایت و نیز نام کاربری و رمزعبوری برای ورود به پیشخوان وردپرس وارد کنید. ازنظر امنیتی، بهتر است که از نام کاربری به‌غیر از admin در این قسمت استفاده کنید. برای رمزعبور هم می‌توانید خودتان رمزعبور قدرتمندی وارد کنید یا به وردپرس اجازه دهید تا رمزعبوری مناسب برایتان انتخاب کند.

در‌ادامه، باید ایمیل خود را وارد کنید و تصمیم بگیرید که آیا می‌خواهید موتورهای جست‌وجو صفحات وب‌سایت شما را index کنند یا خیر؛ البته معمولاً همه ما دوست داریم که وب‌سایت را Crawlerهای گوگل یا سایر موتورهای جست‌وجو ببینند:

مشخصات مثل نام وب‌سایت، نام کاربری، رمزعبور و موارد مشابه را وارد کنید

بعد از اینکه موارد خواسته‌شده را وارد کردید، روی دکمه Install WordPress در پایین صفحه کلیک کنید. در این‌ صورت، صفحه‌ای برایتان باز خواهد شد که نتیجه نصب وردپرس را به شما گزارش خواهد داد:

روی گزینه Log In کلیک کنید

بعد از اینکه با استفاده از نام کاربری و رمزعبوری که در قسمت قبلی وارد کرده‌اید به سیستم وارد شوید، به داشبورد اختصاصی وردپرس می‌توانید دسترسی پیدا و وب‌سایت خود را مدیریت کنید:

با موفقیت وارد داشبورد اختصاصی وردپرس شدید

بعد از اینکه وردپرس را با موفقیت نصب کردید، بهتر است اقداماتی انجام دهید تا از تمدید خودکار گواهی SSL خود مطمئن شوید.

گام هفتم: تمدید گواهی SSL

گواهینامه‌های SSL صادر‌شده Let’s Encrypt نود روز اعتبار دارند. برای اینکه مطمئن باشید که قبل از انقضای تاریخ این گواهی‌ها مجدداً تمدید می‌شوند، فرایند تمدید را می‌توانید به‌صورت خودکار درآورید. یکی از راه‌های انجام این کار، استفاده از برنامه زمان‌بندی با Cron است.

در‌ادامه، نحوه انجام این کار را آموزش می‌دهیم. در این مثال، با استفاده از یک اسکریپت فرایند تمدید گواهی خودکار و پیکربندی Nginx نیز مجدداً انجام خواهد شد. برای شروع، اسکریپتی با نام ssl_renew.sh ایجاد کنید:

nano ssl_renew.sh

با اضافه‌کردن کد زیر به اسکریپت، فرایند تمدید گواهی را به‌طورخودکار درآورید و پیکربندی وب سرور خود را نیز دوباره انجام دهید. فراموش نکنید که نام کاربری درج‌شده در این مثال را باید با نام کاربر غیرریشه خود جایگزین کنید:

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

پس از اتمام ویرایش، فایل را ببندید و با استفاده از دستور زیر آن را اجرایی کنید:

chmod +x ssl_renew.sh

سپس، فایل corntab را با استفاده از sudo باز کنید:

sudo crontab -e

اگر برای اولین‌بار است که این فایل را باز می‌کنید، از شما خواسته می‌شود تا نرم‌افزاری برای این منظور انتخاب کنید:

Output
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 (1):
...

در انتهای فایل، خط زیر را اضافه کنید:

...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

با این کار، دستور هر ۵ دقیقه انجام خواهد شد. بعد از ۵ دقیقه، فایل cron.log را بررسی کنید و ببینید که آیا درخواست تمدید موفقیت‌آمیز بوده است یا خیر:

tail -f /var/log/cron.log

در‌صورتی‌که با خروجی زیر مواجه شدید، یعنی مراحل با موفقیت انجام شده است:

Output
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

با استفاده از کلیدهای ترکیبی Ctrl+C، از ترمینال خود خارج شوید. در‌صورتی‌که بخواهید اجرای کار هرروز تکرار شود، می‌توانید آخرین خط کد را به‌صورت زیر تغییر دهید:

...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

در این‌ صورت، فرایند تمدید گواهی هرروز در ساعت ۱۲ انجام خواهد شد. همچنین، می‌توانید گزینه –dry-run را از اسکریپت حذف کنید:

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

جمع‌بندی

در این مطلب آموزشی از بلاگ پارس پک، نحوه نصب وردپرس برای وب سرور Nginx با Docker Compose را آموزش دادیم. تمامی مراحل به‌صورت گام‌به‌گام و با درج تمامی کدها و دستورهای لازم آمده است تا دغدغه‌ای برای نصب وردپرس با استفاده از این ابزار نداشته باشید. در انتها نیز، نحوه خودکارسازی دریافت گواهی SSL از Let’s Encrypt با استفاده از Cron را توضیح دادیم.

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

۱. Docker Compose چیست؟

Docker Compose ابزاری است که برای کمک به تعریف و به‌اشتراک‌گذاری برنامه‌های چندکانتینری توسعه یافته است. 

۲. آیا استفاده از Docker Compose رایگان است؟

بله، این ابزار هنگام نصب Docker روی سیستم شما اضافه می‌شود و استفاده از آن نیز رایگان است.

۳. آیا تمدید گواهی SSL از Let’s Encrypt رایگان است؟

بله، همان‌طور‌که صدور گواهی SSL از Let’s Encrypt رایگان است، تمدید این گواهی هم به‌‌رایگان انجام خواهد شد.