مقدمه
وردپرس یک سیستم مدیریت محتوا (CMS) رایگان و منبع باز است که بر روی پایگاه داده MySQL با پردازش PHP ساخته شده است. به لطف معماری پلاگین و سیستم قالب توسعه پذیر آن، بیشتر مدیریت آن را می توان از طریق رابط وب انجام داد. به همین دلیل است که وردپرس یک انتخاب محبوب در هنگام ایجاد انواع مختلف وب سایت ها، از وبلاگ گرفته تا صفحات محصول و سایت های تجارت الکترونیک است.
اجرای وردپرس معمولاً شامل نصب یک LAMP (Linux، Apache، MySQL و PHP) یا LEMP (Linux، Nginx، MySQL و PHP) است که میتواند زمانبر باشد. با این حال، با استفاده از ابزارهایی مانند Docker و Docker Compose، میتوانید فرآیند تنظیم پشته دلخواه خود و نصب وردپرس را ساده کنید. به جای نصب اجزای جداگانه با دست، میتوانید از تصاویر استفاده کنید که مواردی مانند کتابخانهها، فایلهای پیکربندی و متغیرهای محیط را استاندارد میکنند. سپس، این تصاویر را در کانتینرها اجرا کنید، فرآیندهای جدا شده ای که روی یک سیستم عامل مشترک اجرا می شوند. علاوه بر این، با استفاده از Compose، میتوانید چندین کانتینر – به عنوان مثال، یک برنامه کاربردی و پایگاه داده – را برای برقراری ارتباط با یکدیگر هماهنگ کنید.
در این آموزش، نصب وردپرس چند کانتینری را خواهید ساخت. کانتینرهای شما شامل پایگاه داده MySQL، وب سرور Nginx و خود وردپرس خواهد بود. همچنین با دریافت گواهینامه های TLS/SSL با Let’s Encrypt برای دامنه ای که می خواهید با سایت خود مرتبط شود، نصب خود را ایمن خواهید کرد. در نهایت، یک cron job برای تمدید گواهینامه های خود راه اندازی می کنید تا دامنه شما امن بماند.
پیش نیازها
- سروری که اوبونتو را اجرا می کند، به همراه یک کاربر غیر ریشه با امتیازات
sudo
و فایروال فعال. - Docker روی سرور شما نصب شده باشد.
- Docker Compose روی سرور شما نصب شده باشید.
- یک نام دامنه ثبت شده این آموزش از دامنه شما در کل استفاده خواهد کرد.
- هر دو رکورد DNS زیر برای سرور شما تنظیم شده است.
رکوردی با your_domain که به آدرس IP عمومی سرور شما اشاره دارد.
رکوردی با www.your_domain که به آدرس IP عمومی سرور شما اشاره دارد.
مرحله 1 – تعریف پیکربندی وب سرور
قبل از اجرای هر کانتینری، اولین قدم شما این است که پیکربندی را برای وب سرور Nginx خود تعریف کنید. فایل پیکربندی شما شامل برخی از بلوکهای موقعیت مکانی خاص وردپرس، به همراه یک بلوک مکان برای هدایت درخواستهای تأیید Let’s Encrypt به مشتری Certbot برای تمدید خودکار گواهی است.
ابتدا یک فهرست پروژه برای راه اندازی وردپرس خود ایجاد کنید. در این مثال به آن وردپرس گفته می شود. در صورت تمایل می توانید نام این دایرکتوری را به شکل دیگری انجام دهید:
mkdir wordpress
سپس به دایرکتوری بروید:
cd wordpress
بعد، یک دایرکتوری برای فایل پیکربندی بسازید:
mkdir nginx-conf
فایل را با nano
یا ویرایشگر مورد علاقه خود باز کنید:
nano nginx-conf/nginx.conf
در این فایل، یک بلوک سرور با دستورالعملهایی برای نام سرور و ریشه سند و بلوکهای مکان اضافه کنید تا درخواست مشتری Certbot برای گواهیها، پردازش PHP و درخواستهای دارایی ثابت را هدایت کنید.
کد زیر را به فایل اضافه کنید. مطمئن شوید که 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;
}
}
بلوک سرور ما شامل اطلاعات زیر است
دستورالعمل ها:
listen
: این به Nginx میگوید در پورت 80 گوش دهد، که به شما امکان میدهد از پلاگین Webroot Certbot برای درخواستهای گواهی خود استفاده کنید. توجه داشته باشید که هنوز پورت 443 را وارد نکردهاید — پس از دریافت موفقیتآمیز گواهیهای خود، پیکربندی خود را برای گنجاندن SSL بهروزرسانی خواهید کرد.server_name
: نام سرور شما و بلوک سروری که باید برای درخواست ها به سرور شما استفاده شود را مشخص می کند. مطمئن شوید که در این خط your_domain را با نام دامنه خود جایگزین کنید.index
: این دستورالعمل فایل هایی را تعریف می کند که در هنگام پردازش درخواست ها به سرور شما به عنوان نمایه استفاده می شوند. شما ترتیب پیشفرض اولویت را در اینجا تغییر دادید و index.php را جلوی index.html منتقل کردید تا Nginx در صورت امکان فایلهایی به نام index.php را اولویت بندی کند.root
: این دستورالعمل دایرکتوری ریشه را برای درخواست های سرور شما نامگذاری می کند. این دایرکتوری، /var/www/html، به عنوان یک نقطه نصب در زمان ساخت توسط دستورالعمل های موجود در Dockerfile وردپرس شما ایجاد می شود. این دستورالعملهای Dockerfile همچنین تضمین میکند که فایلهای نسخه وردپرس در این حجم نصب میشوند.
بلوک های مکان:
location ~ /.well-known/acme-challenge
: این بلوک مکان درخواست ها را به دایرکتوری .well-known رسیدگی می کند، جایی که Certbot یک فایل موقت را برای تأیید اینکه DNS دامنه شما به سرور شما حل می شود قرار می دهد. با وجود این پیکربندی، میتوانید از پلاگین Webroot Certbot برای دریافت گواهینامه برای دامنه خود استفاده کنید.location
/: در این بلوک مکان، دستورالعمل try_files برای بررسی فایلهایی که با درخواستهای URI منطبق هستند استفاده میشود. با این حال، به جای بازگرداندن وضعیت 404 Not Found به عنوان پیش فرض، کنترل را به فایل index.php وردپرس با آرگومان های درخواست منتقل می کنید.location ~ \.php
$: این بلوک مکان پردازش PHP را انجام می دهد و این درخواست ها را به ظرف وردپرس شما پراکسی می کند. از آنجایی که تصویر داکر وردپرس شما بر اساس تصویر php:fpm خواهد بود، گزینه های پیکربندی که مختص پروتکل FastCGI هستند را نیز در این بلوک قرار می دهید. Nginx به یک پردازنده PHP مستقل برای درخواست های PHP نیاز دارد. در این حالت، این درخواستها توسط پردازنده php-fpm که با تصویر php:fpm ارائه میشود، رسیدگی میشود. علاوه بر این، این بلوک مکان شامل دستورالعملها، متغیرها و گزینههای مخصوص FastCGI است که درخواستهای پروکسی برنامه وردپرس را که در ظرف وردپرس شما اجرا میشود، تنظیم میکند، فهرست ترجیحی را برای URI درخواست تجزیه شده تنظیم میکند و درخواستهای URI را تجزیه میکند.location ~ /\.ht
: این بلوک فایلهای .htaccess را مدیریت میکند زیرا Nginx به آنها سرویس نمیدهد. دستورالعمل deny_all تضمین می کند که فایل های .htaccess هرگز به کاربران ارائه نخواهند شد.location = /favicon.ico, location = /robots.txt
: این بلوک ها تضمین می کنند که درخواست های /favicon.ico و /robots.txt ثبت نمی شوند.location ~* \.(css|gif|ico|jpeg|jpg|js|png)
$: این بلوک ثبت درخواستهای دارایی ثابت را غیرفعال میکند و تضمین میکند که این داراییها بسیار قابل ذخیرهسازی هستند، زیرا معمولاً سرویس دهی آنها گران است.
پس از اتمام ویرایش فایل را ذخیره کرده و ببندید. اگر از نانو استفاده میکنید، این کار را با فشار دادن CTRL+X، Y و سپس ENTER انجام دهید.با پیکربندی Nginx خود، می توانید به سمت ایجاد متغیرهای محیطی بروید تا در زمان اجرا به ظروف برنامه و پایگاه داده خود منتقل شوند.
مرحله 2 – تعریف متغیرهای محیطی
پایگاه داده و کانتینرهای برنامه وردپرس شما نیاز به دسترسی به متغیرهای محیطی خاصی در زمان اجرا دارند تا داده های برنامه شما باقی بماند و در دسترس برنامه شما باشد. این متغیرها شامل اطلاعات حساس و غیر حساس هستند: مقادیر حساس برای رمز عبور ریشه 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
شامل یک رمز عبور برای حساب مدیریت ریشه، و همچنین نام کاربری و رمز عبور دلخواه شما برای پایگاه داده برنامه شما است.پس از اتمام ویرایش فایل را ذخیره کرده و ببندید.
از آنجایی که فایل env شما حاوی اطلاعات حساسی است، میخواهید مطمئن شوید که در فایلهای gitignore و .dockerignore پروژه شما گنجانده شده است. این به Git و Docker میگوید چه فایلهایی را به ترتیب در مخازن Git و تصاویر Docker کپی نکنید.
با git init:
git init
سپس یک فایل .gitignore ایجاد و باز کنید:
nano .gitignore
env را به فایل اضافه کنید:
.env
پس از اتمام ویرایش فایل را ذخیره کرده و ببندید.
به همین ترتیب، افزودن .env به فایل .dockerignore یک اقدام احتیاطی خوب است تا زمانی که از این دایرکتوری به عنوان زمینه ساخت خود استفاده می کنید، در کانتینرهای شما قرار نگیرد.
فایل را باز کنید:
nano .dockerignore
env را به فایل اضافه کنید:
.env
در زیر این، می توانید به صورت اختیاری فایل ها و دایرکتوری های مرتبط با توسعه برنامه خود را اضافه کنید:
.env
.git
docker-compose.yml
.dockerignore
پس از اتمام کار فایل را ذخیره کرده و ببندید.
با در اختیار داشتن اطلاعات حساس خود، اکنون می توانید به تعریف خدمات خود در یک فایل docker-compose.yml بروید.
مرحله 3 – تعریف خدمات با Docker Compose
فایل docker-compose.yml شما حاوی تعاریف سرویس برای راه اندازی شما خواهد بود. یک سرویس در Compose یک کانتینر در حال اجرا است و تعاریف سرویس اطلاعاتی را در مورد نحوه اجرای هر کانتینر مشخص می کند.
با استفاده از Compose، میتوانید سرویسهای مختلفی را برای اجرای برنامههای چند کانتینری تعریف کنید، زیرا Compose به شما امکان میدهد این سرویسها را با شبکهها و حجمهای مشترک به یکدیگر پیوند دهید. این برای راه اندازی فعلی شما مفید خواهد بود زیرا شما کانتینرهای مختلفی را برای پایگاه داده، برنامه وردپرس و وب سرور خود ایجاد می کنید. همچنین یک محفظه برای اجرای کلاینت Certbot برای دریافت گواهی برای وب سرور خود ایجاد خواهید کرد.
برای شروع، فایل docker-compose.yml را ایجاد و باز کنید:
nano docker-compose.yml
کد زیر را برای تعریف نسخه فایل Compose و سرویس پایگاه داده db خود اضافه کنید:
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 شامل گزینه های زیر است:
image
: این به Compose میگوید چه تصویری را برای ایجاد ظرف بکشید. شما در حال پین کردن تصویر mysql:8.0 در اینجا هستید تا از درگیری های بعدی جلوگیری کنید زیرا تصویر mysql:latest همچنان به روز می شود. برای اطلاعات بیشتر در مورد پین کردن نسخه و اجتناب از تداخل وابستگی، مستندات Docker را در بهترین شیوههای Dockerfile بخوانید.Container_name
: نامی برای کانتینر مشخص می کند.restart
: این خط مشی راه اندازی مجدد کانتینر را مشخص می کند. پیشفرض خیر است، اما شما کانتینر را برای راهاندازی مجدد تنظیم کردهاید مگر اینکه به صورت دستی متوقف شود.env_file
: این گزینه به Compose میگوید که میخواهید متغیرهای محیطی را از فایلی به نام .env که در زمینه ساخت شما قرار دارد اضافه کنید. در این مورد، زمینه ساخت دایرکتوری فعلی شما است.envirronment
: این گزینه به شما اجازه می دهد تا متغیرهای محیطی اضافی، فراتر از آنهایی که در فایل .env تعریف شده است، اضافه کنید. شما متغیر MYSQL_DATABASE را برابر با wordpress قرار می دهید تا نامی برای پایگاه داده برنامه خود ارائه دهید. از آنجایی که این اطلاعات غیر حساس است، می توانید آن را مستقیماً در فایل docker-compose.yml قرار دهید.volumes
: در اینجا، شما در حال نصب یک حجم با نام به نام dbdata در پوشه /var/lib/mysql در کانتینر هستید. این دایرکتوری استاندارد داده برای MySQL در اکثر توزیع ها است.command
: این گزینه دستوری را برای لغو دستور پیش فرض CMD برای تصویر مشخص می کند. در این مورد خاص، شما یک گزینه به دستور استاندارد mysqld Docker image اضافه میکنید که سرور MySQL را روی کانتینر راهاندازی میکند. این گزینه، –default-authentication-plugin=mysql_native_password، متغیر سیستم –default-authentication-plugin را بر روی mysql_native_password قرار می دهد و مشخص می کند که کدام مکانیزم احراز هویت باید بر درخواست های احراز هویت جدید به سرور حاکم باشد. از آنجایی که PHP و در نتیجه تصویر وردپرس شما از پیشفرض احراز هویت جدید MySQL پشتیبانی نمیکند، باید این تنظیمات را برای احراز هویت کاربر پایگاه داده برنامه خود انجام دهید.- networks: این مشخص می کند که سرویس برنامه شما به شبکه برنامه-شبکه ملحق می شود که در پایین فایل آن را تعریف می کنید.
سپس، در زیر تعریف سرویس 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
در این تعریف سرویس، شما کانتینر خود را نامگذاری می کنید و یک خط مشی راه اندازی مجدد را تعریف می کنید، همانطور که با سرویس db انجام دادید. شما همچنین در حال اضافه کردن برخی گزینه های خاص به این کانتاینر هستید:
depends_on
: این گزینه تضمین می کند که کانتینرهای شما به ترتیب وابستگی شروع می شوند و ظرف وردپرس بعد از ظرف db شروع می شود. برنامه وردپرس شما به وجود پایگاه داده و کاربر برنامه شما متکی است، بنابراین بیان این ترتیب وابستگی باعث می شود برنامه شما به درستی شروع شود.image
: برای این تنظیم، از تصویر وردپرس 5.1.1-fpm-alpine استفاده می کنید. همانطور که در مرحله 1 توضیح داده شد، استفاده از این تصویر تضمین می کند که برنامه شما دارای پردازنده php-fpm است که Nginx برای مدیریت پردازش PHP به آن نیاز دارد. این نیز یک تصویر آلپاین است که از پروژه Alpine Linux مشتق شده است که به کاهش اندازه کلی تصویر شما کمک می کند. برای کسب اطلاعات بیشتر در مورد مزایا و معایب استفاده از تصاویر آلپاین و اینکه آیا این برای برنامه شما منطقی است یا خیر، بحث کامل را در بخش Image Variants در صفحه تصویر وردپرس Docker Hub مرور کنید.env_file
: مجدداً مشخص میکنید که میخواهید مقادیر را از فایل .env خود استخراج کنید، زیرا اینجاست که کاربر پایگاه داده برنامه و رمز عبور خود را تعریف کردهاید.environment
: در اینجا، شما از مقادیری که در فایل .env خود تعریف کرده اید استفاده می کنید، اما آنها را به نام متغیرهایی که تصویر وردپرس انتظار دارد، اختصاص می دهید: WORDPRESS_DB_USER و WORDPRESS_DB_PASSWORD. شما همچنین در حال تعریف یک WORDPRESS_DB_HOST هستید، که سرور MySQL خواهد بود که روی ظرف db که در پورت پیشفرض MySQL، 3306 قابل دسترسی است، اجرا میشود. WORDPRESS_DB_NAME شما همان مقداری خواهد بود که در تعریف سرویس MySQL برای MYSQL_DATABASE خود تعیین کردهاید: wordpress.volumes
: شما در حال نصب یک حجم به نام wordpress در /var/www/html mountpoint ایجاد شده توسط تصویر وردپرس هستید. استفاده از یک حجم نامگذاری شده در این روش به شما امکان می دهد کد برنامه خود را با سایر کانتینرها به اشتراک بگذارید.network
: شما همچنین در حال اضافه کردن ظرف وردپرس به شبکه برنامه-شبکه هستید.
سپس، در زیر تعریف سرویس برنامه کاربردی wordpress، تعریف زیر را برای سرویس 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
در اینجا، شما ظرف خود را نام گذاری می کنید و آن را به ترتیب اولیه به ظرف وردپرس وابسته می کنید. شما همچنین از یک تصویر آلپاین استفاده می کنید – تصویر 1.15.12-alpine Nginx.
این تعریف سرویس شامل گزینه های زیر نیز می شود:
ports
: این پورت 80 را برای فعال کردن گزینههای پیکربندی که در فایل nginx.conf خود در مرحله 1 تعریف کردهاید، نمایش میدهد.volumes
: در اینجا، شما ترکیبی از ولوم های نامگذاری شده و پایه های اتصال را تعریف می کنید:- wordpress:/var/www/html: این کد برنامه وردپرس شما را در پوشه /var/www/html قرار میدهد، دایرکتوری که به عنوان ریشه در بلوک سرور Nginx خود تنظیم کردهاید.
./nginx-conf:/etc/nginx/conf.d
: با این کار پوشه پیکربندی Nginx روی هاست را به دایرکتوری مربوطه در کانتینر متصل میکند، و اطمینان حاصل میکند که هر تغییری که در فایلهای روی هاست ایجاد میکنید در هاست منعکس میشود.certbot-etc:/etc/letsencrypt
: با این کار گواهینامه ها و کلیدهای Let’s Encrypt مربوط به دامنه شما در دایرکتوری مناسب روی کانتینر نصب می شود.
شما همچنین این ظرف را به شبکه برنامه-شبکه اضافه کرده اید.
در نهایت، در زیر تعریف وب سرور خود، آخرین تعریف سرویس خود را برای سرویس 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 sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
این تعریف به Compose میگوید که تصویر certbot/certbot را از Docker Hub بکشد. همچنین از حجم های نامگذاری شده برای به اشتراک گذاشتن منابع با ظرف Nginx استفاده می کند، از جمله گواهینامه های دامنه و کلید در certbot-etc و کد برنامه در وردپرس.مجدداً، برای تعیین اینکه ظرف certbot باید پس از اجرا شدن سرویس وب سرور راه اندازی شود، ازdependent_on استفاده کرده اید.شما همچنین یک گزینه فرمان اضافه کرده اید که یک فرمان فرعی را برای اجرا با دستور certbot پیش فرض ظرف مشخص می کند. فرمان فرعی certonly گواهی با گزینه های زیر دریافت می کند:
--webroot
: این به Certbot می گوید که از افزونه webroot برای قرار دادن فایل ها در پوشه webroot برای احراز هویت استفاده کند. این افزونه به روش اعتبارسنجی HTTP-01 بستگی دارد، که از یک درخواست HTTP برای اثبات اینکه Certbot میتواند به منابعی از سروری که به نام دامنه معین پاسخ میدهد دسترسی داشته باشد، استفاده میکند.--webroot-path
: این مسیر دایرکتوری webroot را مشخص می کند.--email
: ایمیل مورد نظر شما برای ثبت نام و بازیابی.--agree-tos
: این مشخص می کند که شما با توافقنامه مشترک ACME موافقت می کنید.--no-eff-email
: این به Certbot می گوید که شما نمی خواهید ایمیل خود را با Electronic Frontier Foundation (EFF) به اشتراک بگذارید. در صورت تمایل این را حذف کنید.--staging
: این به Certbot میگوید که میخواهید از محیط مرحلهبندی Let’s Encrypt برای دریافت گواهیهای آزمایشی استفاده کنید. استفاده از این گزینه به شما امکان می دهد گزینه های پیکربندی خود را آزمایش کنید و از محدودیت های احتمالی درخواست دامنه اجتناب کنید. برای اطلاعات بیشتر در مورد این محدودیتها، لطفاً اسناد محدودیتهای نرخ Let’s Encrypt را بخوانید.-d
: این به شما امکان می دهد نام دامنه هایی را که می خواهید برای درخواست خود اعمال کنید، مشخص کنید. در این مورد، your_domain و www.your_domain را وارد کرده اید. مطمئن شوید که این ها را با دامنه خود جایگزین کنید.
در زیر تعریف سرویس certbot، تعاریف شبکه و حجم خود را اضافه کنید:
... volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
کلید ولوم سطح بالای شما حجم های certbot-etc، wordpress و dbdata را تعریف می کند. هنگامی که داکر حجم ها را ایجاد می کند، محتویات جلد در یک فهرست در سیستم فایل میزبان، /var/lib/docker/volumes/ که توسط داکر مدیریت می شود، ذخیره می شود. سپس محتویات هر جلد از این دایرکتوری به هر ظرفی که از حجم استفاده می کند سوار می شود. به این ترتیب، امکان اشتراک گذاری کد و داده بین کانتینرها وجود دارد.
شبکه برنامه شبکه پل تعریف شده توسط کاربر ارتباط بین کانتینرهای شما را امکان پذیر می کند زیرا آنها در همان میزبان دایمون داکر هستند. این کار ترافیک و ارتباطات درون برنامه را ساده میکند، زیرا همه پورتها را بین کانتینرها در همان شبکه پل باز میکند، بدون اینکه هیچ پورتی در معرض دنیای بیرون قرار دهد. بنابراین، ظروف db، wordpress و وب سرور شما می توانند با یکدیگر ارتباط برقرار کنند و شما فقط باید پورت 80 را برای دسترسی front-end به برنامه در معرض دید قرار دهید.
فایل 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 sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
پس از اتمام ویرایش فایل را ذخیره کرده و ببندید. با تعاریف خدمات خود، آماده راه اندازی کانتینرها و آزمایش درخواست های گواهینامه خود هستید.
مرحله 4 – دریافت گواهینامه ها و اعتبارنامه های 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
پس از تکمیل، سرویسهای db، wordpress و وبسرور شما بالا میآیند و ظرف certbot با یک پیام وضعیت 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
هر چیزی غیر از بالا در ستون State برای سرویسهای db، wordpress یا وبسرور، یا وضعیت خروجی غیر از 0 برای کانتینر certbot به این معنی است که ممکن است لازم باشد گزارشهای سرویس را با دستور docker-compose logs بررسی کنید:
docker-compose logs service_name
اکنون میتوانید بررسی کنید که گواهیهای شما با docker-compose exec به محفظه وب سرور نصب شدهاند:
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 با متغیر به روز شده است:
...
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 sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...
اکنون می توانید docker-compose را برای ایجاد مجدد ظرف certbot اجرا کنید. همچنین گزینه –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: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0
با در اختیار داشتن گواهیهای خود، میتوانید پیکربندی Nginx خود را برای گنجاندن SSL تغییر دهید.
مرحله 5 – تغییر پیکربندی وب سرور و تعریف سرویس
فعال کردن SSL در پیکربندی Nginx شامل اضافه کردن یک تغییر مسیر HTTP به HTTPS، مشخص کردن گواهینامه SSL و مکانهای کلیدی، و افزودن پارامترهای امنیتی و هدرها است.از آنجایی که میخواهید سرویس وبسرویسکننده را مجدداً ایجاد کنید تا این موارد اضافه شده را شامل شود، اکنون میتوانید آن را متوقف کنید:
docker-compose stop webserver
قبل از اصلاح فایل پیکربندی، پارامتر امنیتی توصیه شده Nginx را از Certbot با استفاده از curl دریافت کنید:
curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/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 ^ https://$host$request_uri? 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; } }
بلوک سرور HTTP، webroot را برای درخواستهای تمدید Certbot به دایرکتوری .well-known/acme-challenge مشخص میکند. همچنین شامل یک دستورالعمل بازنویسی است که درخواست های HTTP را به دایرکتوری ریشه به HTTPS هدایت می کند.
بلوک سرور HTTPS ssl و http2 را فعال می کند. برای مطالعه بیشتر در مورد نحوه تکرار HTTP/2 در پروتکل های HTTP و مزایایی که می تواند برای عملکرد وب سایت داشته باشد، لطفاً مقدمه نحوه راه اندازی Nginx با پشتیبانی HTTP/2 در اوبونتو 18.04 را بخوانید.
این بلوک همچنین شامل گواهی SSL و مکانهای کلیدی شما به همراه پارامترهای امنیتی Certbot توصیهشده است که در nginx-conf/options-ssl-nginx.conf ذخیره کردهاید.
علاوه بر این، برخی از سرفصلهای امنیتی گنجانده شدهاند که به شما امکان میدهند در مواردی مانند سایتهای تست سرور SSL Labs و Security Headers رتبهبندی A دریافت کنید. این هدرها عبارتند از X-Frame-Options، X-Content-Type-Options، Referrer Policy، Content-Security-Policy و X-XSS-Protection. سرصفحه امنیت حمل و نقل سخت HTTP (HSTS) توضیح داده شده است – این را فقط در صورتی فعال کنید که مفاهیم را درک کرده باشید و عملکرد “پیش بارگذاری” آن را ارزیابی کرده باشید.
دستورالعملهای ریشه و فهرست شما نیز در این بلوک قرار دارند، همانطور که بقیه بلوکهای مکان مخصوص وردپرس که در مرحله 1 مورد بحث قرار گرفتهاند.پس از اتمام ویرایش، فایل را ذخیره کرده و ببندید.
قبل از ایجاد مجدد سرویس وب سرور، باید یک نقشه 443 پورت را به تعریف سرویس وب سرور خود اضافه کنید.
فایل docker-compose.yml خود را باز کنید:
nano docker-compose.yml
در تعریف سرویس وب سرور، نگاشت پورت زیر را اضافه کنید:
...
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 sammy@your_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
پس از اتمام ویرایش فایل را ذخیره کرده و ببندید.
سرویس وب سرور را دوباره ایجاد کنید:
docker-compose up -d --force-recreate --no-deps webserver
خدمات خود را با docker-compose ps بررسی کنید:
docker-compose ps
خروجی باید نشان دهد که خدمات db، wordpress و وب سرور شما در حال اجرا هستند:
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
با در حال اجرا بودن کانتینرها، می توانید نصب وردپرس خود را از طریق رابط وب کامل کنید.
مرحله 6 – تکمیل نصب از طریق رابط وب
در حالی که ظروف شما در حال اجرا است، نصب را از طریق رابط وب وردپرس به پایان برسانید.
در مرورگر وب خود، به دامنه سرور خود بروید. فراموش نکنید که your_domain را با نام دامنه خود جایگزین کنید:
https://your_domain
زبانی را که می خواهید استفاده کنید انتخاب کنید:
پس از کلیک بر روی Continue، در صفحه راه اندازی اصلی قرار می گیرید، جایی که باید یک نام برای سایت خود و یک نام کاربری انتخاب کنید. ایده خوبی است که در اینجا یک نام کاربری به یاد ماندنی (به جای “admin”) و یک رمز عبور قوی انتخاب کنید. می توانید از رمز عبوری که وردپرس به صورت خودکار تولید می کند استفاده کنید یا رمز عبور خود را ایجاد کنید.در نهایت، باید آدرس ایمیل خود را وارد کنید و تصمیم بگیرید که آیا میخواهید موتورهای جستجو را از فهرست کردن سایت خود منصرف کنید یا خیر:
با کلیک بر روی Install WordPress در پایین صفحه، به یک اعلان ورود هدایت می شوید:
پس از ورود به سیستم، به داشبورد مدیریت وردپرس دسترسی خواهید داشت:
با تکمیل نصب وردپرس، می توانید اقداماتی را انجام دهید تا اطمینان حاصل شود که گواهینامه های SSL شما به طور خودکار تمدید می شوند.
مرحله 7 – تمدید گواهینامه ها
گواهینامه های Let’s Encrypt به مدت 90 روز معتبر هستند. شما می توانید یک فرآیند تمدید خودکار را تنظیم کنید تا اطمینان حاصل کنید که آنها از بین نمی روند. یکی از راههای انجام این کار ایجاد شغل با برنامه زمانبندی cron است. در مثال زیر، یک کار 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
این اسکریپت ابتدا باینری docker-compose را به متغیری به نام COMPOSE اختصاص می دهد و گزینه –no-ansi را مشخص می کند که دستورات docker-compose را بدون کاراکترهای کنترل ANSI اجرا می کند. سپس همین کار را با داکر باینری انجام می دهد. در نهایت، به دایرکتوری پروژه ~/wordpress تغییر می کند و دستورات docker-compose زیر را اجرا می کند:
-
docker-compose
: با این کار یک ظرف certbot شروع می شود و دستور ارائه شده در تعریف سرویس certbot شما لغو می شود. به جای استفاده از دستور فرعی certonly، از دستور فرعی renew استفاده می شود که گواهی هایی را که نزدیک به انقضا هستند تمدید می کند. همچنین شامل گزینه –dry-run برای تست اسکریپت شما می باشد. docker-compose kill
: این یک سیگنال SIGHUP را به کانتینر وب سرور ارسال می کند تا پیکربندی Nginx را دوباره بارگیری کند.
سپس سیستم docker prune را اجرا می کند تا تمام کانتاینر و تصاویر استفاده نشده را حذف کند.
پس از اتمام ویرایش فایل را ببندید. با دستور زیر آن را قابل اجرا کنید:
chmod +x ssl_renew.sh
سپس، فایل crontab root خود را باز کنید تا اسکریپت تمدید در یک بازه زمانی مشخص اجرا شود:
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، برای ضبط خروجی مربوطه از کار ایجاد می شود.
پس از پنج دقیقه، 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 در ترمینال خود خارج شوید.
می توانید فایل crontab را برای تنظیم یک بازه روزانه تغییر دهید. به عنوان مثال، برای اجرای اسکریپت هر روز در ظهر، آخرین خط فایل را مانند زیر تغییر دهید:
...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
شما همچنین می خواهید گزینه –dry-run را از اسکریپت 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 && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af
کار cron شما تضمین میکند که گواهیهای Let’s Encrypt شما با تمدید آنها در زمانی که واجد شرایط هستند، از بین نمیروند. همچنین میتوانید چرخش log را با ابزار Logrotate در اوبونتو 22.04 / 20.04 تنظیم کنید تا فایلهای گزارش خود را بچرخانید و فشرده کنید.
نتیجه
در این آموزش از Docker Compose برای ایجاد نصب وردپرس با وب سرور Nginx استفاده کردید. به عنوان بخشی از این گردش کار، گواهیهای TLS/SSL را برای دامنهای که میخواهید با سایت وردپرس خود مرتبط کنید، دریافت کردید. علاوه بر این، یک کار cron ایجاد کردید تا در صورت لزوم این گواهی ها را تمدید کنید.