Установка WordPress с помощью Docker Compose: отладка сервисов и веб-сервера

WordPress – это свободная и открытая система управления контентом (CMS), построенная на базе данных MySQL с обработкой PHP. Благодаря своей расширяемой архитектуре на основе плагинов и шаблонов, а также возможности управлять через веб-интерфейс, WordPress является популярным выбором при создании различных веб-сайтов – от блогов до посадочных страниц и eCommerce сайтов.

Запуск WordPress обычно включает в себя установку стека LAMP (Linux, Apache, MySQL и PHP) или LEMP (Linux, Nginx, MySQL и PHP), что может занять много времени. Однако с помощью таких инструментов, как Docker и Docker Compose, вы можете упростить процесс настройки стека и установки WordPress. Вместо ручной установки отдельных компонентов вы можете использовать образы, которые многое стандартизируют (библиотеки, конфигурационные файлы и переменные среды), и запускать эти образы в изолированных контейнерах, которые выполняются в общей операционной системе. Кроме того, с помощью Compose вы можете координировать работу нескольких контейнеров – например, приложения и базы данных – и связать их друг с другом.

В предыдущем мануале мы создали мультиконтейнерную установку WordPress и получили для нее сертификаты TLS/SSL от Let’s Encrypt. В этом мануале мы настроим веб-сервер для поддержки этих сертификатов, обновим сервисы и автоматизируем обновление сертификатов с помощью cron.

Примечание: Этот мануал является продолжением мануала Установка WordPress с помощью Docker Compose: сервисы и SSL-сертификаты.

1: Отладка конфигурации веб-сервера и определения сервиса

Для включения SSL в конфигурации Nginx нужно настроить перенаправление HTTP на HTTPS, указать SSL-сертификаты и расположение ключей, а также добавить параметры и заголовки безопасности.

Поскольку мы собираемся заново собрать сервис webserver для включения новых параметров, сейчас его можно остановить:

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/options-ssl-nginx.conf

Эта команда сохранит параметры в файле options-ssl-nginx.conf, расположенном в каталоге nginx-conf.

Затем удалите конфигурационный файл Nginx, который вы создали в предыдущем мануале :

rm nginx-conf/nginx.conf

Откройте другую версию файла:

nano nginx-conf/nginx.conf

Добавьте следующий код в файл, чтобы перенаправить HTTP на HTTPS и добавить учетные данные SSL, протоколы и заголовки безопасности. Не забудьте заменить example.com своим собственным доменом:

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
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 example.com www.example.com;
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/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;
}
}

Блок server HTTP определяет webroot для запросов Certbot на обновление в каталоге .well-known/acme-challenge. Он также содержит директиву rewrite, которая направляет HTTP-запросы в корневой каталог на HTTPS.

Читайте также: Настройка Nginx с поддержкой HTTP/2 в Ubuntu 18.04

Этот блок также включает сертификат SSL, расположение ключей и рекомендуемые параметры безопасности Certbot, которые мы сохранили в nginx-conf/options-ssl-nginx.conf.

Кроме того, мы включили некоторые заголовки безопасности, которые позволят нам получить оценку A на сайтах SSL Labs и Security Headers. Эти заголовки: X-Frame-OptionsX-Content-Type-OptionsReferrer PolicyContent-Security-Policy и X-XSS-Protection. Заголовок HTTP Strict Transport Security (HSTS) закомментирован – включите его, только если вы понимаете последствия и оценили его «предварительную загрузку».

Директивы root и index тоже находятся в здесь, как и остальные блоки location для WordPress, которые обсуждались в разделе 1 предыдущего мануала.

Сохраните и закройте файл.

Прежде чем заново создать сервис webserver, необходимо добавить в определение сервиса отображение портов 443.

Откройте файл docker-compose.yml:

nano docker-compose.yml

В определение webserver добавьте следующее отображение портов:

...
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 8host@example.com --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com
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

Вы должны увидеть выходные данные, указывающие, что ваши сервисы db, wordpress и webserver работают:

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

Теперь, когда контейнеры запущены, вы можете завершить установку WordPress через веб-интерфейс.

2: Завершение установки WordPress через веб-интерфейс

Когда контейнеры работают, вы можете завершить установку через веб-интерфейс WordPress.

В веб-браузере откройте домен вашего сервера.

https://example.com

Выберите из списка язык, который вы хотели бы использовать.

После нажатия кнопки Continue вы попадете на главную страницу настройки, где нужно выбрать имя своего сайта и имя пользователя. Рекомендуется выбрать уникальное и запоминающееся имя пользователя (а не «admin») и надежный пароль. Вы можете использовать пароль, который WordPress генерирует автоматически, или выбрать свой собственный.

Затем нужно ввести свой адрес электронной почты и указать, хотите ли вы запретить поисковым системам индексировать ваш сайт.

Нажав на кнопку Install WordPress внизу страницы, вы увидите форму для входа в систему.

После входа вы получите доступ к панели управления WordPress.

После завершения установки WordPress вы можете добавить настройки для автоматического обновления сертификатов SSL.

3: Автоматическое обновление сертификатов

Сертификаты Let’s Encrypt действительны в течение 90 дней, поэтому вам нужно настроить автоматический процесс обновления, чтобы они своевременно возобновлялись. Один из способов сделать это – создать задачу для утилиты cron. В этом случае мы создадим задачу cron для периодического запуска скрипта, который будет обновлять наши сертификаты и перезагружать конфигурацию Nginx.

Сначала откройте скрипт ssl_renew.sh:

nano ssl_renew.sh

Добавьте следующий код в скрипт, чтобы обновлять сертификаты и перезагружать конфигурацию веб-сервера. Не забудьте заменить приведенное здесь имя пользователя именем вашего пользователя:

#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --no-ansi"
cd /home/8host/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver

Этот сценарий сначала присваивает двоичный файл docker-compose переменной COMPOSE и указывает параметр —no-ansi, который будет запускать команды docker-compose без управляющих символов ANSI. Затем он переходит в каталог проекта ~/wordpress и запускает следующие команды docker-compose:

  • docker-compose run: запустит контейнер certbot и переопределит команду, указанную в определении сервиса certbot. Вместо подкоманды certonly мы используем здесь подкоманду renew, которая обновит сертификаты, срок действия которых близок к истечению. Мы включили опцию —dry-run, чтобы протестировать скрипт.
  • docker-compose kill: отправит сигнал SIGHUP в контейнер webserver для перезагрузки конфигурации Nginx. Дополнительную информацию об использовании этого процесса для перезагрузки конфигурации Nginx можно найти в этом блоге Docker о развертывании официального образа Nginx.

Закройте файл. Сделайте его исполняемым:

chmod +x ssl_renew.sh

Откройте root crontab, чтобы настроить запуск сценария обновления с определенной периодичностью.

sudo crontab -e

Если вы впервые редактируете этот файл, вам будет предложено выбрать редактор:

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/8host/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

Это позволит установить интервал между задачами в пять минут, чтобы вы могли проверить, работает ли запрос на обновление должным образом. Мы также создали лог, cron.log, для записи результатов работы.

Через пять минут проверьте cron.log, чтобы увидеть, успешно ли выполнен запрос на обновление:

tail -f /var/log/cron.log

Вы должны увидеть вывод, подтверждающий успешное обновление:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** 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/example.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Теперь вы можете изменить файл crontab, чтобы установить интервал в один день. Например, чтобы запускать скрипт каждый день в полдень, вы должны изменить последнюю строку файла так:

0 12 * * * /home/8host/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"
cd /home/8host/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver

Демон cron гарантирует, что ваши сертификаты Let’s Encrypt не утратят силу, потому что сценарий будет обновлять их вовремя. Вы также можете настроить ротацию логов с помощью утилиты Logrotate.

Читайте также: Управление логами с помощью Logrotate в Ubuntu 16.04

Заключение

В этом мануале вы использовали Docker Compose для установки WordPress с веб-сервером Nginx. В рамках этого рабочего процесса вы получили сертификаты TLS/SSL для домена, который связан с вашим сайтом WordPress. Кроме того, вы создали задачу cron для обновления этих сертификатов по мере необходимости.

В качестве дополнительных рекомендаций по повышению производительности и избыточности сайта мы предлагаем вам обратиться к статьям:

Tags: , , , , ,