71 KiB
source |
---|
https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose-ru |
Введение
WordPress — бесплатная система управления контентом (CMS) с открытым исходным кодом, которая опирается на базу данных MySQL и обрабатывает запросы с помощью PHP. Благодаря огромному количеству плагинов и системе шаблонов, а также тому факту, что большая часть административных функций может производиться через веб-интерфейс, #WordPress завоевала популярность среди создателей самых разных сайтов, от блогов и страниц с описанием продукта и до сайтов электронной торговли.
Для запуска WordPress, как правило, требуется установка стека LAMP ( #Linux, #Apache, #MySQL и #PHP) или LEMP (Linux, #Nginx, MySQL и PHP), что может занять много времени. С помощью таких инструментов, как Docker и Docker Compose, вы можете упростить процесс настройки предпочитаемого стека и установки WordPress. Вместо установки отдельных компонентов вручную, вы можете использовать образы, которые обладают такими стандартными элементами, как библиотеки, файлы конфигурации и переменные среды, и запускать эти образы в контейнерах, т. е. изолированных процессах, запущенных в общей операционной системе. Кроме того, используя Compose, вы можете координировать действия нескольких контейнеров, например приложения и базы данных, которые будут коммуницировать друг с другом.
В этом обучающем руководстве вы будете выполнять установку WordPress с несколькими контейнерами. Ваши контейнеры будут включать базу данных MySQL, веб-сервер Nginx и непосредственно WordPress. Также вы должны будете обеспечить защиту установки, получая с помощью Let’s Encrypt сертификаты TLS/SSL для доменов, которые вы хотите привязать к вашему сайту. Наконец, вы настроите задание cron
для обновления ваших сертификатов, чтобы ваш домен оставался защищенным.
Предварительные требования
Для данного обучающего руководства вам потребуется следующее:
- Сервер на базе #Ubuntu 18.04, а также пользователь без прав root с привилегиями
sudo
и активный брандмауэр. Дополнительную информацию о настройке этих параметров см. в руководстве по первоначальной настройке сервера. - Система #Docker, установленная на сервере в соответствии с шагами 1 и 2 руководства Установка и использование Docker в Ubuntu 18.04.
- #docker-compose, установленный на сервере, в соответствии с шагом 1 руководства Установка Docker Compose в Ubuntu 18.04.
- Зарегистрированное доменное имя. В этом обучающем руководстве мы будем использовать example.com. Вы можете получить бесплатный домен на Freenom или зарегистрировать доменное имя по вашему выбору.
- На вашем сервере должны быть настроены обе нижеследующие записи DNS. Вы можете воспользоваться введением в работу с DigitalOcean DNS, чтобы получить подробную информацию о добавлении доменов в учетную запись DigitalOcean, если вы используете этот способ:
- Запись
A
, гдеexample.com
указывает на публичный IP-адрес вашего сервера. - Запись
A
, гдеwww.example.com
указывает на публичный IP-адрес вашего сервера.
- Запись
Шаг 1 — Настройка конфигурации веб-сервера
Перед запуском контейнеров прежде всего необходимо настроить конфигурацию нашего веб-сервера Nginx. Наш файл конфигурации будет включать несколько специфических для Wordpress блоков расположения наряду с блоками расположения, которые будут направлять передаваемые Let’s Encrypt запросы верификации клиенту Certbot для автоматизированного обновления сертификатов.
Во-первых, создайте директорию проекта для настройки WordPress с именем wordpress
и перейдите в эту директорию:
mkdir wordpress && cd wordpress
Затем создайте директорию для файла конфигурации:
mkdir nginx-conf
Откройте файл с помощью nano
или своего любимого редактора:
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 #Certbot для наших запросов сертификатов. Обратите внимание, что мы пока не будем включать порт443
, мы обновим нашу конфигурацию и добавим SSL после успешного получения наших сертификатов.server_name
: этот элемент определяет имя вашего сервера и серверный блок, которые должны использоваться для запросов к вашему серверу. Обязательно заменитеexample.com
в этой строке на ваше собственное доменное имя.index
: директиваindex
определяет файлы, которые будут использоваться в качестве индексов при обработке запросов к вашему серверу. Здесь мы изменили порядок приоритета по умолчанию, поставивindex.php
передindex.html
, в результате чего Nginx будет давать приоритет файлам с именемindex.php
при наличии возможности.root
: наша директиваroot
назначает имя корневой директории для запросов к нашему серверу. Эта директория,/var/www/html
, создается в качестве точки монтирования в момент сборки с помощью инструкций в Dockerfile WordPress. Эти инструкции 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
, мы также добавим параметры конфигурации, принадлежащие протоколу 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. Информацию о серверных блоках и блоках расположения см. в статье Знакомство с сервером Nginx и алгоритмы выбора блоков расположения.
Сохраните и закройте файл после завершения редактирования. Если вы используете nano
, нажмите CTRL
+X
, Y
, затем ENTER
.
После настройки конфигурации Nginx вы можете перейти к созданию переменных среды для передачи в контейнеры приложения и базы данных во время исполнения.
Шаг 2 — Настройка переменных среды
Контейнеры базы данных и приложения WordPress должны получить доступ к определенным переменным среды в момент выполнения для сохранения данных приложения и предоставления доступа к этим данным для вашего приложения. Эти переменные включают чувствительные и нечувствительные данные: к чувствительным данным относятся root-пароль MySQL и пароль и пользователь базы данных приложения, а к нечувствительным данным относится информация об имени и хосте базы данных приложения.
Вместо того, чтобы задавать эти значения в нашем файле Docker Compose, основном файле, который содержит информацию о том, как наши контейнеры будут работать, мы можем задать чувствительные значения в файле .env
и ограничить его распространение. Это не позволит скопировать эти значения в репозиторий нашего проекта и открыть их для общего доступа.
В главной директории проекта ~/wordpress
, откройте файл с именем .env
:
nano .env
Конфиденциальные значения, которые мы зададим в этом файле, включают пароль для нашего root-пользователя MySQL, имя пользователя и пароль, которые WordPress будет использовать для доступа к базе данных.
Добавьте в файл следующие имена и значения переменных: Обязательно предоставьте здесь ваши собственные значения для каждой переменной:
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password
Мы включили пароль для административной учетной записи root, а также предпочитаемые имя пользователя и пароль для нашей базы данных приложения.
Сохраните и закройте файл после завершения редактирования.
Поскольку ваш файл .env
содержит чувствительную информацию, вы можете убедиться, что в файлы .gitignore
и .dockerignore
вашего проекта включены инструкции, указывающие Git и Docker, какие файлы не копировать в ваши репозитории Git и образы Docker.
Если вы планируете использовать #git для контроля версий, инициализируйте текущую рабочую директорию в качестве репозитория с помощью 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 позволяет привязать эти службы к общим сетям и томам. Это будет полезно для нашей текущей настройки, поскольку мы создадим различные контейнеры для нашей базы данных, приложения WordPress и веб-сервера. Также мы создадим контейнер для запуска клиента 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
: данный параметр определяет политику перезапуска контейнера. По умолчанию установлено значениеno
, но мы задали значение, согласно которому контейнер будет перезапускаться, пока не будет остановлен вручную.env_file
: этот параметр указывает Compose, что мы хотим добавить переменные среды из файла с именем.env
, расположенного в контексте сборки. В этом случае в качестве контекста сборки используется наша текущая директория.environment
: этот параметр позволяет добавить дополнительные переменные среды, не определенные в файле.env
. Мы настроим переменнуюMYSQL_DATABASE
со значениемwordpress
, которая будет предоставлять имя нашей базы данных приложения. Поскольку эта информация не является чувствительной, мы можем включить ее напрямую в файлdocker-compose.yml
.volumes
: здесь мы монтируем именованный том с названиемdbdata
в директорию/var/lib/mysql
в контейнере. Это стандартная директория данных в большинстве дистрибутивов.command
: данный параметр указывает команду, которая будет переопределять используемое по умолчанию значение инструкции CMD для образа. В нашем случае мы добавим параметр для стандартной командыmysqld
образа Docker, которая запускает сервер MySQL в контейнере. Эта опция-default-authentication-plugin=mysql_native_password
устанавливает для системной переменной-default-authentication-plugin
значениеmysql_native_password
, которое указывает, какой механизм аутентификации должен управлять новыми запросами аутентификации для сервера. Поскольку PHP и наш образ WordPress не будут поддерживать новое значение аутентификации MySQL по умолчанию, мы должны внести изменения, чтобы выполнить аутентификацию пользователя базы данных приложения.networks
: данный параметр указывает, что служба приложения будет подключаться к сетиapp-network
, которую мы определим внизу файла.
Затем под определением службы db
добавьте определение для вашей службы приложения wordpress
:
...
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
: для этой настройки мы будем использовать образ Wordpress5.11-fpm-alpine
. Как было показано в шаге 1, использование этого образа гарантирует, что наше приложение будет иметь процессорphp-fpm
, который требуется Nginx для обработки PHP. Это еще и образalpine
, полученный из проекта Alpine Linux, который поможет снизить общий размер образа. Дополнительную информацию о преимуществах и недостатках использования образовalpine
, а также о том, имеет ли это смысл в случае вашего приложения, см. в полном описании в разделе Варианты образа на странице образа WordPress на Docker Hub.env_file
: и снова мы укажем, что хотим загрузить значения из файла.env
, поскольку там мы определили пользователя базы данных приложения и пароль.environment
: здесь мы будем использовать значения, определенные в файле.env
, но мы привяжем их к именам переменных, которые требуются для образа WordPress:WORDPRESS_DB_USER
иWORDPRESS_DB_PASSWORD
. Также мы определяем значениеWORDPRESS_DB_HOST
, которое будет указывать сервер MySQL, который будет работать в контейнереdb
, доступный на используемом по умолчанию порту MySQL3306
. Наше значениеWORDPRESS_DB_NAME
будет тем же, которое мы указали при определении службы MySQL дляMYSQL_DATABASE
:wordpress
.volumes
: мы монтируем том с именемwordpress
на точку монтирования/var/www/html
, созданную образом WordPress. Использование тома с именем таким образом позволит разделить наш код приложения с другими контейнерами.networks
: мы добавляем контейнерwordpress
в сетьapp-network
.
Далее под определением службы приложения wordpress
добавьте следующее определение для службы Nginx webserver
:
...
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 1.15.12-alpine
.
Это определение службы также включает следующие параметры:
ports
: этот параметр открывает порт80
, чтобы активировать параметры конфигурации, определенные нами в файлеnginx.conf
в шаге 1.volumes
: здесь мы определяем комбинацию названных томов и связанных монтируемых образов:wordpress:/var/www/html
: этот параметр будет монтировать код нашего приложения WordPress в директорию/var/www/html
, директорию, которую мы задали в качествеroot
директории в нашем серверном блоке Nginx../nginx-conf:/etc/nginx/conf.d
: этот элемент будет монтировать директорию конфигурации Nginx на хост в соответствующую директорию в контейнере, гарантируя, что любые изменения, которые мы вносим в файлы на хосте, будут отражены в контейнере.certbot-etc:/etc/letsencrypt
: этот элемент будет монтировать соответствующие сертификаты и ключи Let’s Encrypt для нашего домена в соответствующую директорию контейнера.
Здесь мы снова добавили этот контейнер в сеть app-network
.
Наконец, под определением webserver
добавьте последнее определение для службы 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@example.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com
Это определение попросит Compose извлекать образ certbot/certbot
из Docker Hub. Также оно использует имена томов для обмена ресурсами с контейнером Nginx, включая доменные сертификаты и ключ в certbot-etc
и код приложения в wordpress
.
Мы использовали depends_on
, чтобы указать, что контейнер certbot
следует запускать только после запуска службы webserver
.
Также мы включили параметр command
, указывающий субкоманду для запуска с используемой контейнером по умолчанию командой 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
: данный элемент позволяет указать доменные имена, которые вы хотите использовать для вашего запроса. В нашем случае мы включилиexample.com
иwww.example.com
. Обязательно замените эти данные на имя вашего домена.
Под определением службы certbot
добавьте определения сети и тома:
...
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
будет выглядеть примерно так:
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
, которая будет создавать и запускать наши контейнеры и службы в указанном нами порядке. Если наши запросы доменов будут выполнены успешно, мы увидим корректный статус выхода в нашем выводе и нужные сертификаты, установленные в папке /etc/letsencrypt/live
на контейнере webserver
.
Создайте контейнеры с помощью команды docker-compose up
и флага -d
, которые будут запускать контейнеры db
, wordpress
и webserver
в фоновом режиме:
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
:
Теперь вы можете убедиться, что ваши сертификаты были смонтированы в контейнер webserver
с помощью команды docker-compose 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
:
nano docker-compose.yml
Найдите раздел файла с определением службы certbot
и замените флаг --staging
в параметрах command
на флаг --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@example.com --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com
...
Теперь вы можете запустить команду docker-compose up
для воссоздания контейнера certbot
. Также мы будем использовать параметр --no-deps
, чтобы сообщить Compose о том, что можно пропустить запуск службы webserver
, поскольку она уже запущена:
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
для включения этих нововведений, сейчас вы можете остановить ее работу:
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. Обязательно замените 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 в корневую директорию HTTPS.
Блок сервера HTTPS активирует ssl
и http2
. Дополнительную информацию о том, как выполняется итерация HTTP/2 в протоколах HTTP и какие преимущества это может дать для повышения производительности веб-сайта, см. во вводной части руководства по настройке Nginx с поддержкой HTTP/2 в Ubuntu 18.04.
Этот блок также включает расположение наших сертификата SSL и ключа, а также рекомендованные параметры безопасности Certbot, которые мы сохранили в nginx-conf/options-ssl-nginx.conf
.
Кроме того, мы включили ряд заголовков безопасности, которые позволят нам получить оценки A на сайтах серверных тестов SSL Labs и Security Headers. Эти заголовки включают X-Frame-Options
, X-Content-Type-Options
, Referrer Policy
, Content-Security-Policy
и X-XSS-Protection
. Заголовок HTTP Strict Transport Security (Строгая безопасность передачи информации по протоколу HTTP)
закомментирован, активируйте этот элемент, только если вы понимаете возможные последствия и оценили его «предварительно загруженный» функционал.
Наши директивы root
и index
также расположены в этом блоке, равно как и остальные блоки расположения WordPress, описанные в шаге 1.
После завершения редактирования сохраните и закройте файл.
Перед повторным созданием службы webserver
вам потребуется добавить распределение порта 443
в определение службы webserver
.
Откройте ваш файл 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 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
:
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
Выберите язык, который вы хотите использовать:
После нажатия Continue (Продолжить) вы перейдете на главную страницу настройки, где вам нужно будет выбрать имя вашего сайта и пользователя. Рекомендуется выбрать запоминающееся имя пользователя (не просто «admin») и надежный пароль. Вы можете использовать пароль, который генерирует WordPress автоматически, или задать собственный пароль.
Наконец, вам нужно будет ввести ваш адрес электронной почты и указать, хотите ли вы, чтобы движки поисковых систем могли индексировать ваш сайт:
После нажатия Install WordPress (Установить Wordpress) внизу страницы на экране появится запрос выполнения входа:
После входа вы получите доступ к панели управления WordPress:
После завершения установки WordPress вы можете выполнить определенные действия, необходимые для гарантии того, что ваши сертификаты SSL будут обновляться автоматически.
Шаг 7 — Обновление сертификатов
Сертификаты Let’s Encrypt действительны в течение 90 дней, поэтому вам нужно будет настроить автоматический процесс обновления, чтобы гарантировать, что сертификаты не окажутся просроченными. Один из способов — создание задания с помощью утилиты планирования cron
. В нашем случае мы настроим задание для cron
с помощью скрипта, который будет обновлять наши сертификаты и перезагружать конфигурацию Nginx.
Откройте скрипт под названием ssl_renew.sh
:
Добавьте следующий код в скрипт, чтобы обновить ваши сертификаты и перезагрузить конфигурацию веб-сервера. Не забудьте заменить приведенное в качестве примера имя пользователя своим именем пользователя без прав root:
#!/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. Затем он делает то же самое с двоичным файлом docker
. В заключение он меняет директорию проекта на ~/wordpress
и запускает следующие команды docker-compose
:
docker-compose run
: данный параметр запускает контейнерcertbot
и переопределяет параметрcommand
, указанный в определении службыcertbot
. Вместо использования субкомандыcertonly
мы используем здесь субкомандуrenew
, которая будет обновлять сертификаты, срок действия которых близок к окончанию. Мы включили параметр-dry-run
, чтобы протестировать наш скрипт.docker-compose kill
: данный параметр отправляет сигналSIGHUP
контейнеруwebserver
для перезагрузки конфигурации Nginx. Дополнительную информацию об использовании этого процесса для перезагрузки конфигурации Nginx см. в этой публикации блога Docker, посвященной развертыванию официального образа Nginx с помощью Docker.
После этого он выполняет команду docker system prune
для удаления всех неиспользуемых контейнеров и образов.
Закройте файл после завершения редактирования. Сделайте его исполняемым:
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]:
...
Добавьте внизу файла следующую строку:
...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
В результате будет установлен интервал в 5 минут для выполнения работы, и вы можете проверить, работает ли запрос обновления так, как предполагается. Также мы создали файл журнала, cron.log
, чтобы записывать соответствующий вывод выполнения задания.
Через 5 минут проверьте 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/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 не окажутся устаревшими, обновляя их в случае истечения срока действия. Также вы можете настроить замену журнала с помощью утилиты Logrotate, которая будет выполнять ротацию и сжатие файлов журнала.
Заключение
В этом руководстве вы использовали Docker Compose для создания установки WordPress с веб-сервером Nginx. В рамках этого рабочего процесса вы получили сертификаты TLS/SSL для домена, который вы хотите подключить к вашему сайту WordPress. Кроме того, вы создали задание cron
для обновления этих сертификатов при необходимости.
В качестве дополнительных мер по повышению производительности сайта и создания запаса мощности, вы можете ознакомиться со следующими статьями, посвященными передаче и поддержке активов WordPress:
Если вы заинтересованы в изучении контейнеризированного рабочего процесса с помощью Kubernetes, вы также можете ознакомиться со следующими материалами: