tech-tips/Программное обеспечение/LEMP-стек/Установка WordPress с помощью Docker Compose DigitalOcean.md

920 lines
71 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
source: https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose-ru
---
![[intro-to-cloud.d49bc5f7.jpeg]]
## Введение
[WordPress](https://wordpress.org/) — бесплатная [система управления контентом (CMS)](https://www.digitalocean.com/community/tutorials/digitalocean-community-glossary#content-management-system) с открытым исходным кодом, которая опирается на базу данных [MySQL](https://www.mysql.com/) и обрабатывает запросы с помощью [PHP](https://www.php.net/). Благодаря огромному количеству плагинов и системе шаблонов, а также тому факту, что большая часть административных функций может производиться через веб-интерфейс, #WordPress завоевала популярность среди создателей самых разных сайтов, от блогов и страниц с описанием продукта и до сайтов электронной торговли.
Для запуска WordPress, как правило, требуется установка стека [LAMP](https://www.digitalocean.com/community/tutorials/digitalocean-community-glossary#lamp) ( #Linux, #Apache, #MySQL и #PHP) или [LEMP](https://www.digitalocean.com/community/tutorials/digitalocean-community-glossary#lemp) (Linux, #Nginx, MySQL и PHP), что может занять много времени. С помощью таких инструментов, как [Docker](https://www.docker.com/) и [Docker Compose](https://docs.docker.com/compose/), вы можете упростить процесс настройки предпочитаемого стека и установки WordPress. Вместо установки отдельных компонентов вручную, вы можете использовать _образы_, которые обладают такими стандартными элементами, как библиотеки, файлы конфигурации и переменные среды, и запускать эти образы в онтейнерах_, т. е. изолированных процессах, запущенных в общей операционной системе. Кроме того, используя Compose, вы можете координировать действия нескольких контейнеров, например приложения и базы данных, которые будут коммуницировать друг с другом.
В этом обучающем руководстве вы будете выполнять установку WordPress с несколькими контейнерами. Ваши контейнеры будут включать базу данных MySQL, веб-сервер Nginx и непосредственно WordPress. Также вы должны будете обеспечить защиту установки, получая с помощью [Lets Encrypt](https://letsencrypt.org/) сертификаты TLS/SSL для доменов, которые вы хотите привязать к вашему сайту. Наконец, вы настроите задание [`cron`](https://www.digitalocean.com/community/tutorials/how-to-schedule-routine-tasks-with-cron-and-anacron-on-a-vps) для обновления ваших сертификатов, чтобы ваш домен оставался защищенным.
## Предварительные требования
Для данного обучающего руководства вам потребуется следующее:
- Сервер на базе #Ubuntu 18.04, а также пользователь без прав root с привилегиями `sudo` и активный брандмауэр. Дополнительную информацию о настройке этих параметров см. в [руководстве по первоначальной настройке сервера](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04).
- Система #Docker, установленная на сервере в соответствии с шагами 1 и 2 руководства [Установка и использование Docker в Ubuntu 18.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04).
- #docker-compose, установленный на сервере, в соответствии с шагом 1 руководства [Установка Docker Compose в Ubuntu 18.04](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04).
- Зарегистрированное доменное имя. В этом обучающем руководстве мы будем использовать example.com. Вы можете получить бесплатный домен на [Freenom](http://www.freenom.com/en/index.html) или зарегистрировать доменное имя по вашему выбору.
- На вашем сервере должны быть настроены обе нижеследующие записи DNS. Вы можете воспользоваться [введением в работу с DigitalOcean DNS](https://www.digitalocean.com/community/tutorials/an-introduction-to-digitalocean-dns), чтобы получить подробную информацию о добавлении доменов в учетную запись DigitalOcean, если вы используете этот способ:
- Запись `A`, где `example.com` указывает на публичный IP-адрес вашего сервера.
- Запись `A`, где `www.example.com` указывает на публичный IP-адрес вашего сервера.
## Шаг 1 — Настройка конфигурации веб-сервера
Перед запуском контейнеров прежде всего необходимо настроить конфигурацию нашего веб-сервера Nginx. Наш файл конфигурации будет включать несколько специфических для Wordpress блоков расположения наряду с блоками расположения, которые будут направлять передаваемые Lets Encrypt запросы верификации клиенту Certbot для автоматизированного обновления сертификатов.
Во-первых, создайте директорию проекта для настройки WordPress с именем `wordpress` и перейдите в эту директорию:
```shell
mkdir wordpress && cd wordpress
```
Затем создайте директорию для файла конфигурации:
```shell
mkdir nginx-conf
```
Откройте файл с помощью `nano` или своего любимого редактора:
```shell
nano nginx-conf/nginx.conf
```
В этом файле мы добавим серверный блок с директивами для имени нашего сервера и корневой директории документов, а также блок расположения для направления запросов сертификатов от клиента Certbot, обработки PHP и запросов статичных активов.
Добавьте в файл следующий код. Обязательно замените `example.com` на ваше доменное имя.
```
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
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](https://certbot.eff.org/docs/using.html#webroot) #Certbot для наших запросов сертификатов. Обратите внимание, что мы пока е_ будем включать порт `443`, мы обновим нашу конфигурацию и добавим SSL после успешного получения наших сертификатов.
- `server_name`: этот элемент определяет имя вашего сервера и серверный блок, которые должны использоваться для запросов к вашему серверу. Обязательно замените `example.com` в этой строке на ваше собственное доменное имя.
- `index`: директива `index` определяет файлы, которые будут использоваться в качестве индексов при обработке запросов к вашему серверу. Здесь мы изменили порядок приоритета по умолчанию, поставив `index.php` перед `index.html`, в результате чего Nginx будет давать приоритет файлам с именем `index.php` при наличии возможности.
- `root`: наша директива `root` назначает имя корневой директории для запросов к нашему серверу. Эта директория, `/var/www/html`, [создается в качестве точки монтирования](https://github.com/docker-library/wordpress/blob/07958d19ed465fb7fe50626be740d88a2c2260a7/php7.2/fpm-alpine/Dockerfile#L53) в момент сборки с помощью инструкций в [Dockerfile WordPress](https://github.com/docker-library/wordpress/blob/07958d19ed465fb7fe50626be740d88a2c2260a7/php7.2/fpm-alpine/Dockerfile). Эти инструкции Dockerfile также гарантируют, что файлы релиза WordPress монтируются в этот том.
**Блоки расположения:**
- `location ~ /.well-known/acme-challenge`: этот блок расположения будет обрабатывать запросы в директории `.well-known`, где Certbot будет размещать временный файл для подтверждения того, что DNS для нашего домена будет работать с нашим сервером. Настроив данную конфигурацию, мы сможем использовать плагин webroot Certbot для получения сертификатов для нашего домена.
- `location /`: в этом блоке расположения мы будем использовать директиву `try_files` для проверки файлов, соответствующих отдельным запросам URI. Вместо того, чтобы возвращать по умолчанию статус 404 `не найдено`, мы будем передавать контроль файлу `index.php` Wordpress с аргументами запроса.
- `location ~\.php$`: этот блок расположения будет обрабатывать PHP-запросы и проксировать эти запросы в наш контейнер `wordpress`. Поскольку наш образ WordPress Docker будет опираться на образ [`php:fpm`](https://github.com/docker-library/php/blob/e63194a0006848edb13b7eff5a7f9d790d679428/7.2/alpine3.9/fpm/Dockerfile), мы также добавим параметры конфигурации, принадлежащие [протоколу FastCGI](https://en.wikipedia.org/wiki/FastCGI), в этот блок. Nginx требует наличия независимого процессора PHP для запросов PHP: в нашем случае эти запросы будут обрабатываться процессором `php-fpm`, который будет включать образ `php:fpm`. Кроме того, этот блок расположения содержит директивы FastCGI, переменные и опции, которые будут проксировать запросы для приложения WordPress, запущенного в нашем контейнере `wordpress`, задавать предпочитаемый индекс захваченного 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)$`: этот блок отключает запись в журнал для запросов статичных активов и гарантирует, что эти активы будут иметь высокую кэшируемость, поскольку обычно их трудно обслуживать.
Дополнительную информацию о проксировании #FastCGI см. в статье [Понимание и реализация проксирования FastCGI в Nginx](https://www.digitalocean.com/community/tutorials/understanding-and-implementing-fastcgi-proxying-in-nginx). Информацию о серверных блоках и блоках расположения см. в статье [Знакомство с сервером Nginx и алгоритмы выбора блоков расположения](https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms).
Сохраните и закройте файл после завершения редактирования. Если вы используете `nano`, нажмите `CTRL`+`X`, `Y`, затем `ENTER`.
После настройки конфигурации Nginx вы можете перейти к созданию переменных среды для передачи в контейнеры приложения и базы данных во время исполнения.
## Шаг 2 — Настройка переменных среды
Контейнеры базы данных и приложения WordPress должны получить доступ к определенным переменным среды в момент выполнения для сохранения данных приложения и предоставления доступа к этим данным для вашего приложения. Эти переменные включают чувствительные и нечувствительные данные: к чувствительным данным относятся **root**-пароль MySQL и пароль и пользователь базы данных приложения, а к нечувствительным данным относится информация об имени и хосте базы данных приложения.
Вместо того, чтобы задавать эти значения в нашем файле Docker Compose, основном файле, который содержит информацию о том, как наши контейнеры будут работать, мы можем задать чувствительные значения в файле `.env` и ограничить его распространение. Это не позволит скопировать эти значения в репозиторий нашего проекта и открыть их для общего доступа.
В главной директории проекта `~/wordpress`, откройте файл с именем `.env`:
```shell
nano .env
```
Конфиденциальные значения, которые мы зададим в этом файле, включают пароль для нашего **root**-пользователя MySQL, имя пользователя и пароль, которые WordPress будет использовать для доступа к базе данных.
Добавьте в файл следующие имена и значения переменных: Обязательно предоставьте здесь **ваши собственные значения** для каждой переменной:
```env
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password
```
Мы включили пароль для административной учетной записи **root**, а также предпочитаемые имя пользователя и пароль для нашей базы данных приложения.
Сохраните и закройте файл после завершения редактирования.
Поскольку ваш файл `.env` содержит чувствительную информацию, вы можете убедиться, что в файлы `.gitignore` и `.dockerignore` вашего проекта включены инструкции, указывающие [Git](https://www.digitalocean.com/community/tutorials/how-to-use-git-a-reference-guide) и **Docker**, какие файлы не копировать в ваши репозитории Git и образы Docker.
Если вы планируете использовать #git для контроля версий, [инициализируйте текущую рабочую директорию в качестве репозитория](https://www.digitalocean.com/community/tutorials/how-to-use-git-a-reference-guide#set-up-and-initialization) с помощью `git init`:
```shell
git init
```
Затем откройте файл `.gitignore`:
```shell
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 позволяет привязать эти службы к общим сетям и томам. Это будет полезно для нашей текущей настройки, поскольку мы создадим различные контейнеры для нашей базы данных, приложения WordPress и веб-сервера. Также мы создадим контейнер для запуска [клиента Certbot](https://certbot.eff.org/), чтобы получить сертификаты для нашего веб-сервера.
Откройте файл `docker-compose.yml`:
```shell
nano docker-compose.yml
```
Добавьте следующий код для определения версии файла Compose и базы данных `db`:
```yaml
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, какой образ будет загружаться для создания контейнера. Мы закрепим здесь [образ](https://github.com/docker-library/mysql/blob/130bd8e46a3da1adfc1732a08c70673e20aa5977/8.0/Dockerfile) [`mysql:8.0`](https://github.com/docker-library/mysql/blob/130bd8e46a3da1adfc1732a08c70673e20aa5977/8.0/Dockerfile), чтобы избежать будущих конфликтов, так как образ `mysql:latest` продолжит обновляться. Дополнительную информацию о закреплении версии и предотвращении конфликтов зависимостей см. в документации Docker в разделе [Рекомендации по работе с Dockerfile](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).
- `container_name`: данный элемент указывает имя контейнера.
- `restart`: данный параметр определяет политику перезапуска контейнера. По умолчанию установлено значение `no`, но мы задали значение, согласно которому контейнер будет перезапускаться, пока не будет остановлен вручную.
- `env_file`: этот параметр указывает Compose, что мы хотим добавить переменные среды из файла с именем `.env`, расположенного в контексте сборки. В этом случае в качестве контекста сборки используется наша текущая директория.
- `environment`: этот параметр позволяет добавить дополнительные переменные среды, не определенные в файле `.env`. Мы настроим переменную `MYSQL_DATABASE` со значением `wordpress`, которая будет предоставлять имя нашей базы данных приложения. Поскольку эта информация не является чувствительной, мы можем включить ее напрямую в файл `docker-compose.yml`.
- `volumes`: здесь мы монтируем именованный [том](https://docs.docker.com/storage/volumes/) с названием `dbdata` в директорию `/var/lib/mysql` в контейнере. Это стандартная директория данных в большинстве дистрибутивов.
- `command`: данный параметр указывает команду, которая будет переопределять используемое по умолчанию значение [инструкции CMD](https://docs.docker.com/engine/reference/builder/#cmd) для образа. В нашем случае мы добавим параметр для стандартной [команды](https://dev.mysql.com/doc/refman/8.0/en/mysqld.html) [`mysqld`](https://dev.mysql.com/doc/refman/8.0/en/mysqld.html) образа Docker, которая запускает сервер MySQL в контейнере. Эта опция `-default-authentication-plugin=mysql_native_password` устанавливает для системной переменной `-default-authentication-plugin` значение `mysql_native_password`, которое указывает, какой механизм аутентификации должен управлять новыми запросами аутентификации для сервера. Поскольку PHP и наш образ WordPress [не будут поддерживать](https://github.com/docker-library/wordpress/issues/313) [новое значение аутентификации MySQL по умолчанию](https://mysqlserverteam.com/upgrading-to-mysql-8-0-default-authentication-plugin-considerations/), мы должны внести изменения, чтобы выполнить аутентификацию пользователя базы данных приложения.
- `networks`: данный параметр указывает, что служба приложения будет подключаться к сети `app-network`, которую мы определим внизу файла.
Затем под определением службы `db` добавьте определение для вашей службы приложения `wordpress`:
```yaml
...
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`: этот параметр гарантирует, что наши контейнеры будут запускаться в порядке зависимости, и контейнер `wordpress` запускается после контейнера `db`. Наше приложение WordPress зависит от наличия базы данных приложения и пользователя, поэтому установка такого порядка зависимостей позволит выполнять запуск приложения корректно.
- `image`: для этой настройки мы будем использовать [образ Wordpress](https://github.com/docker-library/wordpress/blob/07958d19ed465fb7fe50626be740d88a2c2260a7/php7.2/fpm-alpine/Dockerfile) [`5.11-fpm-alpine`](https://github.com/docker-library/wordpress/blob/07958d19ed465fb7fe50626be740d88a2c2260a7/php7.2/fpm-alpine/Dockerfile). Как было показано в [шаге 1](https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose#step-1-%E2%80%94-defining-the-web-server-configuration), использование этого образа гарантирует, что наше приложение будет иметь процессор `php-fpm`, который требуется Nginx для обработки PHP. Это еще и образ `alpine`, полученный из [проекта Alpine Linux](https://alpinelinux.org/), который поможет снизить общий размер образа. Дополнительную информацию о преимуществах и недостатках использования образов `alpine`, а также о том, имеет ли это смысл в случае вашего приложения, см. в полном описании в разделе **Варианты образа** на [странице образа WordPress на Docker Hub](https://hub.docker.com/_/wordpress).
- `env_file`: и снова мы укажем, что хотим загрузить значения из файла `.env`, поскольку там мы определили пользователя базы данных приложения и пароль.
- `environment`: здесь мы будем использовать значения, определенные в файле `.env`, но мы привяжем их к именам переменных, которые требуются для образа WordPress: `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`, [созданную образом WordPress](https://github.com/docker-library/wordpress/blob/07958d19ed465fb7fe50626be740d88a2c2260a7/php7.2/fpm-alpine/Dockerfile#L53). Использование тома с именем таким образом позволит разделить наш код приложения с другими контейнерами.
- `networks`: мы добавляем контейнер `wordpress` в сеть `app-network`.
Далее под определением службы приложения `wordpress` добавьте следующее определение для службы Nginx `webserver`:
```yaml
...
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
```
Мы снова присвоим имя нашему контейнеру и сделаем его зависимым от контейнера `wordpress` в отношении порядка запуска. Также мы используем образ `alpine` — [образ Nginx](https://github.com/nginxinc/docker-nginx/blob/e5123eea0d29c8d13df17d782f15679458ff899e/mainline/stretch/Dockerfile) [`1.15.12-alpine`](https://github.com/nginxinc/docker-nginx/blob/e5123eea0d29c8d13df17d782f15679458ff899e/mainline/stretch/Dockerfile).
Это определение службы также включает следующие параметры:
- `ports`: этот параметр открывает порт `80`, чтобы активировать параметры конфигурации, определенные нами в файле `nginx.conf` в шаге 1.
- `volumes`: здесь мы определяем комбинацию названных томов и [связанных монтируемых образов](https://docs.docker.com/storage/bind-mounts/):
- `wordpress:/var/www/html`: этот параметр будет монтировать код нашего приложения WordPress в директорию `/var/www/html`, директорию, которую мы задали в качестве `root`директории в нашем серверном блоке Nginx.
- `./nginx-conf:/etc/nginx/conf.d`: этот элемент будет монтировать директорию конфигурации Nginx на хост в соответствующую директорию в контейнере, гарантируя, что любые изменения, которые мы вносим в файлы на хосте, будут отражены в контейнере.
- `certbot-etc:/etc/letsencrypt`: этот элемент будет монтировать соответствующие сертификаты и ключи Lets Encrypt для нашего домена в соответствующую директорию контейнера.
Здесь мы снова добавили этот контейнер в сеть `app-network`.
Наконец, под определением `webserver` добавьте последнее определение для службы `certbot`. Обязательно замените адрес электронной почты и доменные имена, перечисленные здесь, на ваши собственные:
```yaml
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@example.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com
```
Это определение попросит Compose извлекать [образ](https://hub.docker.com/r/certbot/certbot/) [`certbot/certbot`](https://hub.docker.com/r/certbot/certbot/) из Docker Hub. Также оно использует имена томов для обмена ресурсами с контейнером Nginx, включая доменные сертификаты и ключ в `certbot-etc` и код приложения в `wordpress`.
Мы использовали `depends_on`, чтобы указать, что контейнер `certbot` следует запускать только после запуска службы `webserver`.
Также мы включили параметр `command`, указывающий субкоманду для запуска с используемой контейнером по умолчанию командой `certbot`. [Субкоманда](https://certbot.eff.org/docs/using.html#certbot-command-line-options) [`certonly`](https://certbot.eff.org/docs/using.html#certbot-command-line-options) будет получать сертификат со следующими параметрами:
- `-webroot`: данный элемент говорит Certbot о необходимости использования плагина webroot для размещения файлов в папке webroot для аутентификации. Работа плагина основана на [методе валидации HTTP-01](https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.2), который использует запрос HTTP, чтобы доказать, что Certbot может получить доступ к ресурсам с сервера, который отвечает на заданное доменное имя.
- `-webroot-path`: данный элемент указывает путь директории webroot.
- `-email`: предпочитаемый адрес электронной почты для регистрации и восстановления.
- `-agree-tos`: данный элемент указывает, что вы принимаете [Соглашение о подписке ACME](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf).
- `-no-eff-email`: данный элемент указывает Certbot, что вы не хотите делиться адресом электронной почты с [Electronic Frontier Foundation](https://www.eff.org/) (EFF). Вы можете пропустить этот элемент.
- `-staging`: данный элемент говорит Certbot, что вы хотите использовать промежуточную среду Lets Encrypt для получения тестовых сертификатов. При использовании этого параметра вы можете протестировать параметры конфигурации и избежать возможных пределов для запросов домена. Дополнительную информацию об этих предельных значениях см. в [документации по ограничениям скорости](https://letsencrypt.org/docs/rate-limits/) Lets Encrypt.
- `d`: данный элемент позволяет указать доменные имена, которые вы хотите использовать для вашего запроса. В нашем случае мы включили `example.com` и `www.example.com`. Обязательно замените эти данные на имя вашего домена.
Под определением службы `certbot` добавьте определения сети и тома:
```yaml
...
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
```
Наш ключ верхнего уровня `volumes` определяет тома `certbot-etc`, `wordpress` и `dbdata`. Когда Docker создает тома, содержимое тома сохраняется в директории файловой системы хоста, `/var/lib/docker/volumes/`, а данным процессом управляет Docker. После этого содержимое каждого тома монтируется из этой директории в любой контейнер, использующий том. Таким образом мы можем делиться кодом и данными между контейнерами.
Создаваемая пользователем мостовая система `app-network` позволяет организовать коммуникацию между нашими контейнерами, поскольку они находятся на одном хосте демона Docker. Это позволяет организовать трафик и коммуникации внутри приложения, поскольку она открывает все порты между контейнерами в одной мостовой сети, скрывая все порты от внешнего мира. Таким образом, наши контейнеры `db`, `wordpress` и `webserver` могут взаимодействовать друг с другом, и нам нужно будет только открыть порт `80` для внешнего доступа к приложению.
Итоговый файл `docker-compose.yml` будет выглядеть примерно так:
```yaml
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@example.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com
volumes:
certbot-etc:
wordpress:
dbdata:
networks:
app-network:
driver: bridge
```
Сохраните и закройте файл после завершения редактирования.
После добавления определений службы вы можете запустить контейнеры и протестировать запросы сертификата.
## Шаг 4 — Получение сертификатов SSL и учетных данных
Мы можем запустить наши контейнеры с помощью команды [`docker-compose up`](https://docs.docker.com/compose/reference/up/), которая будет создавать и запускать наши контейнеры и службы в указанном нами порядке. Если наши запросы доменов будут выполнены успешно, мы увидим корректный статус выхода в нашем выводе и нужные сертификаты, установленные в папке `/etc/letsencrypt/live` на контейнере `webserver`.
Создайте контейнеры с помощью команды [`docker-compose up`](https://docs.docker.com/compose/reference/up/) и флага `-d`, которые будут запускать контейнеры `db`, `wordpress` и `webserver` в фоновом режиме:
```shell
docker-compose up -d
```
Вы увидите вывод, подтверждающий, что ваши службы были успешно созданы:
```
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot ... done
```
Если все будет выполнено успешно, ваши службы `db`, `wordpress` и `webserver` должны иметь статус `Up`, а работа контейнера `certbot` будет завершена с сообщением о статусе `0`:
```
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
```
Если вы увидите любое значение, кроме `Up` в столбце `State` для служб `db`, `wordpress` и `webserver`, или любое сообщение о статусе выхода, отличающееся от `0`, для контейнера `certbot`, проверьте журналы службы с помощью команды [`docker-compose logs`](https://docs.docker.com/compose/reference/logs/):
Теперь вы можете убедиться, что ваши сертификаты были смонтированы в контейнер `webserver` с помощью команды [`docker-compose exec`](https://docs.docker.com/compose/reference/exec/):
```
docker-compose exec webserver ls -la /etc/letsencrypt/live
```
Если запросы сертификата были выполнены успешно, вы увидите следующий результат:
```
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 example.com
```
Теперь, когда вы убедились, что ваш запрос будет выполнен успешно, вы можете изменить определение службы `certbot` для удаления флага `--staging`.
Откройте `docker-compose.yml`:
```shell
nano docker-compose.yml
```
Найдите раздел файла с определением службы `certbot` и замените флаг `--staging` в параметрах `command` на флаг `--force-renewal`, который будет указывать Certbot, что вы хотите запросить новый сертификат с теми же доменами, что и в уже существующем сертификате. Определение службы `certbot` должно будет выглядеть следующим образом:
```yaml
...
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@example.com --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com
...
```
Теперь вы можете запустить команду `docker-compose up` для воссоздания контейнера `certbot`. Также мы будем использовать параметр `--no-deps`, чтобы сообщить Compose о том, что можно пропустить запуск службы `webserver`, поскольку она уже запущена:
```shell
docker-compose up --force-recreate --no-deps certbot
```
Вы увидите вывод, указывающий, что запрос сертификата выполнен успешно:
```
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 example.com
certbot | http-01 challenge for www.example.com
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/example.com/fullchain.pem
certbot | Your key file has been saved at:
certbot | /etc/letsencrypt/live/example.com/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 и добавление параметров безопасности и заголовков.
Поскольку вы будете воссоздавать службу `webserver` для включения этих нововведений, сейчас вы можете остановить ее работу:
```shell
docker-compose stop webserver
```
Прежде чем мы самостоятельно изменим файл конфигурации, нам нужно предварительно получить [рекомендуемые параметры безопасности Nginx](https://github.com/certbot/certbot/blob/master/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx.conf) от Certbot с помощью `curl`:
```shell
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:
```shell
rm nginx-conf/nginx.conf
```
Откройте другую версию файла:
```shell
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;
}
}
```
Блок сервера HTTP указывает webroot для запросов обновления Certbot в директории `.well-known/acme-challenge`. Также он содержит [директиву перезаписи](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite), которая перенаправляет запросы HTTP в корневую директорию HTTPS.
Блок сервера HTTPS активирует `ssl` и `http2`. Дополнительную информацию о том, как выполняется итерация HTTP/2 в протоколах HTTP и какие преимущества это может дать для повышения производительности веб-сайта, см. во вводной части [руководства по настройке Nginx с поддержкой HTTP/2 в Ubuntu 18.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-18-04).
Этот блок также включает расположение наших сертификата SSL и ключа, а также рекомендованные параметры безопасности Certbot, которые мы сохранили в `nginx-conf/options-ssl-nginx.conf`.
Кроме того, мы включили ряд заголовков безопасности, которые позволят нам получить оценки **A** на сайтах серверных тестов [SSL Labs](https://www.ssllabs.com/ssltest/) и [Security Headers](https://securityheaders.com/). Эти заголовки включают [`X-Frame-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options), [`X-Content-Type-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options), [`Referrer Policy`](https://scotthelme.co.uk/a-new-security-header-referrer-policy/), [`Content-Security-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) и [`X-XSS-Protection`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection). Заголовок [HTTP](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) [`Strict Transport Security (Строгая безопасность передачи информации по протоколу HTTP)`](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) закомментирован, активируйте этот элемент, только если вы понимаете возможные последствия и оценили его [«предварительно загруженный» функционал](https://hstspreload.org/).
Наши директивы `root` и `index` также расположены в этом блоке, равно как и остальные блоки расположения WordPress, описанные в [шаге 1](https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose#step-1-%E2%80%94-defining-the-web-server-configuration).
После завершения редактирования сохраните и закройте файл.
Перед повторным созданием службы `webserver` вам потребуется добавить распределение порта `443` в определение службы `webserver`.
Откройте ваш файл `docker-compose.yml`:
В определении службы `webserver` добавьте следующее распределение порта:
```yaml
...
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` будет выглядеть следующим образом после завершения настройки:
```yaml
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@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`:
```shell
docker-compose up -d --force-recreate --no-deps webserver
```
Проверьте ваши службы с помощью команды `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 через веб-интерфейс.
## Шаг 6 — Завершение установки через веб-интерфейс
После запуска контейнеров мы можем завершить установку через веб-интерфейс WordPress.
В браузере перейдите на домен вашего сервера. Не забудьте заменить здесь `example.com` на ваше доменное имя:
```
https://example.com
```
Выберите язык, который вы хотите использовать:
![[wp_language_select.png]]
После нажатия **Continue** (Продолжить) вы перейдете на главную страницу настройки, где вам нужно будет выбрать имя вашего сайта и пользователя. Рекомендуется выбрать запоминающееся имя пользователя (не просто «admin») и надежный пароль. Вы можете использовать пароль, который генерирует WordPress автоматически, или задать собственный пароль.
Наконец, вам нужно будет ввести ваш адрес электронной почты и указать, хотите ли вы, чтобы движки поисковых систем могли индексировать ваш сайт:
![[wp_main_setup.png]]
После нажатия **Install WordPress** (Установить Wordpress) внизу страницы на экране появится запрос выполнения входа:
![[wp_login.png]]
После входа вы получите доступ к панели управления WordPress:
![[wp_main_dash.png]]
После завершения установки WordPress вы можете выполнить определенные действия, необходимые для гарантии того, что ваши сертификаты SSL будут обновляться автоматически.
## Шаг 7 — Обновление сертификатов
Сертификаты Lets Encrypt действительны в течение 90 дней, поэтому вам нужно будет настроить автоматический процесс обновления, чтобы гарантировать, что сертификаты не окажутся просроченными. Один из способов — создание задания с помощью утилиты планирования `cron`. В нашем случае мы настроим задание для `cron` с помощью скрипта, который будет обновлять наши сертификаты и перезагружать конфигурацию Nginx.
Откройте скрипт под названием `ssl_renew.sh`:
Добавьте следующий код в скрипт, чтобы обновить ваши сертификаты и перезагрузить конфигурацию веб-сервера. Не забудьте заменить приведенное в качестве примера имя пользователя своим именем пользователя без прав root:
```shell
#!/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](https://vt100.net/docs/vt510-rm/chapter4.html). Затем он делает то же самое с двоичным файлом `docker`. В заключение он меняет директорию проекта на `~/wordpress` и запускает следующие команды `docker-compose`:
- `docker-compose run`: данный параметр запускает контейнер `certbot` и переопределяет параметр `command`, указанный в определении службы `certbot`. Вместо использования субкоманды `certonly` мы используем здесь субкоманду `renew`, которая будет обновлять сертификаты, срок действия которых близок к окончанию. Мы включили параметр `-dry-run`, чтобы протестировать наш скрипт.
- [`docker-compose kill`](https://docs.docker.com/compose/reference/kill/): данный параметр отправляет сигнал [`SIGHUP`](https://en.wikipedia.org/wiki/SIGHUP) контейнеру `webserver` для перезагрузки конфигурации Nginx. Дополнительную информацию об использовании этого процесса для перезагрузки конфигурации Nginx см. в этой [публикации блога Docker, посвященной развертыванию официального образа Nginx с помощью Docker](https://blog.docker.com/2015/04/tips-for-deploying-nginx-official-image-with-docker/).
После этого он выполняет команду [`docker system prune`](https://docs.docker.com/engine/reference/commandline/system_prune/) для удаления всех неиспользуемых контейнеров и образов.
Закройте файл после завершения редактирования. Сделайте его исполняемым:
```shell
chmod +x ssl_renew.sh
```
Далее откройте **root**-файл `crontab` для запуска скрипта обновления с заданным интервалом:
Если вы в первый раз редактируете этот файл, вам будет предложено выбрать редактор:
```
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]:
...
```
Добавьте внизу файла следующую строку:
```cron
...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
```
В результате будет установлен интервал в 5 минут для выполнения работы, и вы можете проверить, работает ли запрос обновления так, как предполагается. Также мы создали файл журнала, `cron.log`, чтобы записывать соответствующий вывод выполнения задания.
Через 5 минут проверьте `cron.log`, чтобы убедиться, что запрос обновления выполнен успешно:
```shell
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` для настройки ежедневного интервала. Чтобы запускать скрипт каждый день в полдень, например, вы должны изменить последнюю строку файла, которая должна выглядеть следующим образом:
```cron
...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
```
Также вы можете изменить параметр `--dry-run` из скрипта `ssl_renew.sh`:
```shell
#!/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` гарантирует, что ваши сертификаты Lets Encrypt не окажутся устаревшими, обновляя их в случае истечения срока действия. Также вы можете [настроить замену журнала с помощью утилиты Logrotate](https://www.digitalocean.com/community/tutorials/how-to-manage-logfiles-with-logrotate-on-ubuntu-16-04), которая будет выполнять ротацию и сжатие файлов журнала.
## Заключение
В этом руководстве вы использовали Docker Compose для создания установки WordPress с веб-сервером Nginx. В рамках этого рабочего процесса вы получили сертификаты TLS/SSL для домена, который вы хотите подключить к вашему сайту WordPress. Кроме того, вы создали задание `cron` для обновления этих сертификатов при необходимости.
В качестве дополнительных мер по повышению производительности сайта и создания запаса мощности, вы можете ознакомиться со следующими статьями, посвященными передаче и поддержке активов WordPress:
- [Ускорение предоставления актива WordPress с помощью DigitalOcean Spaces CDN](https://www.digitalocean.com/community/tutorials/how-to-speed-up-wordpress-asset-delivery-using-digitalocean-spaces-cdn).
Если вы заинтересованы в изучении контейнеризированного рабочего процесса с помощью Kubernetes, вы также можете ознакомиться со следующими материалами:
- [Настройка WordPress с MySQL с использованием Kubernetes и Helm](https://www.digitalocean.com/community/tutorials/how-to-set-up-wordpress-with-mysql-on-kubernetes-using-helm).