Введение
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. Вы также защитите свою установку, получив TLS/SSL-сертификаты от Let's Encrypt для домена, который вы хотите связать со своим сайтом. Наконец, вы настроите cron-задание для обновления сертификатов, чтобы ваш домен оставался в безопасности.
Предпосылки
- Сервер под управлением Ubuntu с пользователем без прав root, имеющим привилегии
судоИ активный брандмауэр. - Docker установлен на вашем сервере.
- На вашем сервере должен быть установлен Docker Compose.
- Зарегистрированное доменное имя. В этом руководстве будет использоваться ваш домен полностью.
- Для вашего сервера настроены обе следующие записи DNS.
Запись your_domain указывает на публичный IP-адрес вашего сервера.
Запись www.your_domain указывает на публичный IP-адрес вашего сервера.
Шаг 1 — Определение конфигурации веб-сервера
Перед запуском любых контейнеров первым делом необходимо определить конфигурацию веб-сервера Nginx. Файл конфигурации включает несколько блоков location, специфичных для WordPress, а также блок location для перенаправления запросов на проверку Let's Encrypt клиенту Certbot для автоматического обновления сертификатов.
Сначала создайте каталог проекта для вашей установки WordPress. В этом примере он будет называться WordPress. Вы можете назвать этот каталог как-нибудь иначе:
mkdir wordpressЗатем перейдите в каталог:
cd wordpressДалее создайте каталог для файла конфигурации:
mkdir nginx-confФайл с нано Или откройте ваш любимый редактор:
nano nginx-conf/nginx.confВ этом файле добавьте блок сервера с инструкциями по имени сервера и корневому каталогу документов, а также блоки местоположения для направления клиентских запросов Certbot на сертификаты, обработку PHP и запросы на основные средства.
Добавьте следующий код в файл. Не забудьте заменить your_domain на имя вашего домена:
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
} Наш серверный блок содержит следующую информацию:
Инструкции:
слушать: Это указывает Nginx прослушивать порт 80, что позволяет использовать плагин Webroot Certbot для запросов сертификатов. Обратите внимание, что вы ещё не указали порт 443 — вы обновите конфигурацию, включив SSL, после успешного получения сертификатов.имя_сервера: Указывает имя вашего сервера и блок сервера, который следует использовать для запросов к нему. Обязательно замените your_domain на имя вашего домена в этой строке.индекс: Эта директива определяет файлы, которые используются в качестве индексов при обработке запросов к вашему серверу. Вы изменили порядок приоритетов по умолчанию и переместили index.php перед index.html, чтобы Nginx отдавал приоритет файлам с именем index.php, когда это возможно.корень: Эта директива задаёт корневой каталог для запросов к серверу. Этот каталог, /var/www/html, создаётся как точка монтирования во время сборки директивами в Dockerfile WordPress. Эти директивы Dockerfile также гарантируют установку файлов версии WordPress на этом томе.
Расположение блоков:
местоположение ~ /.well-known/acme-challenge: Этот блок обрабатывает запросы к каталогу .well-known, куда Certbot помещает временный файл для проверки того, что DNS-сервер вашего домена разрешается на ваш сервер. С этой конфигурацией вы можете использовать плагин Webroot Certbot для получения сертификата для вашего домена.расположение/: В этом блоке location директива try_files используется для проверки файлов, соответствующих запрошенному URI. Однако вместо возврата статуса 404 «Не найдено», как это происходит по умолчанию, управление передаётся файлу WordPress index.php с аргументами запроса.местоположение ~ \.php$: Этот блок расположения обрабатывает PHP-запросы и перенаправляет их в контейнер WordPress. Поскольку ваш образ WordPress Docker будет основан на образе php:fpm, в этот блок также необходимо включить параметры конфигурации, специфичные для протокола FastCGI. Nginx требует отдельного PHP-процессора для PHP-запросов. В этом случае эти запросы будут обрабатываться процессором php-fpm, входящим в состав образа php:fpm. Кроме того, этот блок расположения содержит специфичные для FastCGI директивы, переменные и параметры, которые настраивают прокси-запросы к приложению WordPress, работающему в контейнере WordPress, устанавливают список предпочтений для URI обработанного запроса и анализируют URI запроса.местоположение ~ /\.ht: Этот блок обрабатывает файлы .htaccess, поскольку Nginx их не обслуживает. Директива deny_all гарантирует, что файлы .htaccess никогда не будут обслуживаться пользователями.местоположение = /favicon.ico, местоположение = /robots.txt: Эти блоки гарантируют, что запросы к /favicon.ico и /robots.txt не будут регистрироваться.местоположение ~* \.(css|gif|ico|jpeg|jpg|js|png)$: Этот блок отключает регистрацию запросов на основные активы и обеспечивает высокую степень кэширования этих активов, поскольку их обслуживание обычно требует больших затрат.
Сохраните и закройте файл после завершения редактирования. Если вы используете 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 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
Определение службы базы данных включает следующие параметры:
изображение: Это указывает Compose, какой образ следует загрузить для создания контейнера. Вы закрепляете здесь образ mysql:8.0, чтобы избежать будущих конфликтов, поскольку образ mysql:latest продолжает обновляться. Подробнее о закреплении версий и предотвращении конфликтов зависимостей см. в документации Docker, посвящённой рекомендациям по использованию Dockerfile.Имя_контейнера: Указывает имя контейнера.перезапуск: Эта политика определяет, будет ли контейнер перезапускаться. Значение по умолчанию — нет, но вы настроили контейнер на перезапуск, если он не будет остановлен вручную.env_file: эта опция сообщает Compose, что вы хотите добавить переменные среды из файла .env, расположенного в вашем контексте сборки. В данном случае контекст сборки — это ваш текущий каталог.среда: Этот параметр позволяет добавлять дополнительные переменные среды, помимо тех, что определены в файле .env. Вы присваиваете переменной MYSQL_DATABASE значение wordpress, чтобы задать имя базы данных вашего приложения. Поскольку эта информация не является конфиденциальной, её можно добавить непосредственно в файл docker-compose.yml.тома: Здесь вы монтируете том с именем dbdata в папке /var/lib/mysql контейнера. Это стандартный каталог данных MySQL в большинстве дистрибутивов.команда: эта опция задаёт команду, переопределяющую команду CMD по умолчанию для образа. В данном случае вы добавляете опцию к стандартной команде образа Docker mysqld, которая запускает сервер MySQL в контейнере. Эта опция, –default-authentication-plugin=mysql_native_password, устанавливает системную переменную –default-authentication-plugin в значение mysql_native_password и указывает, какой механизм аутентификации должен обрабатывать новые запросы на аутентификацию к серверу. Поскольку PHP, а следовательно, и ваш образ WordPress, не поддерживают новую аутентификацию MySQL по умолчанию, вам необходимо настроить её для аутентификации пользователя базы данных вашего приложения.- сети: это указывает, что ваша служба приложений присоединится к сети приложений, которую вы определяете в нижней части файла.
Затем под определением службы базы данных добавьте определение службы приложения 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
В этом определении сервиса вы присваиваете контейнеру имя и определяете политику перезапуска, как и в случае со службой базы данных. Вы также добавляете к этому контейнеру некоторые особые параметры:
зависит_от: этот параметр гарантирует, что ваши контейнеры будут запускаться в порядке зависимостей, при этом контейнер WordPress будет запускаться после контейнера db. Ваше приложение WordPress зависит от наличия базы данных и пользователя приложения, поэтому указание такого порядка зависимостей обеспечит корректный запуск приложения.изображение: Для этой настройки вы будете использовать образ WordPress 5.1.1-fpm-alpine. Как объяснялось в шаге 1, использование этого образа гарантирует, что ваше приложение будет иметь процессор php-fpm, необходимый Nginx для обработки PHP. Это также образ Alpine, полученный из проекта Alpine Linux, что помогает уменьшить общий размер образа. Подробнее о плюсах и минусах использования образов Alpine и о том, целесообразно ли это для вашего приложения, читайте в разделе «Варианты образов» на странице образов WordPress Docker Hub.env_file: Опять же, вы указываете, что хотите извлечь значения из вашего файла .env, поскольку именно там вы определили пользователя и пароль вашей базы данных приложения.среда: Здесь вы используете значения, определенные в файле .env, но присваиваете их именам переменных, ожидаемых образом WordPress: WORDPRESS_DB_USER и WORDPRESS_DB_PASSWORD. Вы также определяете WORDPRESS_DB_HOST, который будет сервером MySQL, работающим в контейнере db, доступном по порту MySQL по умолчанию, 3306. Значение WORDPRESS_DB_NAME будет совпадать со значением, указанным для MYSQL_DATABASE в определении службы MySQL: WordPress.тома: Вы монтируете том с именем WordPress в точку монтирования /var/www/html, созданную образом WordPress. Использование именованного тома таким образом позволяет вам использовать код вашего приложения совместно с другими контейнерами.сеть: Вы также добавляете контейнер WordPress в сеть приложений.
Затем под определением службы приложения WordPress добавьте следующее определение для службы веб-сервера Nginx:
... webserver: depends_on: - wordpress image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network
Здесь вы присваиваете имя контейнеру и делаете его зависимым от контейнера WordPress в изначальном порядке. Также вы используете образ Alpine — образ Nginx 1.15.12-alpine.
Данное определение услуги также включает следующие опции:
порты: Это открывает порт 80 для включения параметров конфигурации, которые вы определили в файле nginx.conf на шаге 1.тома: Здесь вы определяете комбинацию именованных томов и точек монтирования:- wordpress:/var/www/html: Этот код поместит ваше приложение WordPress в папку /var/www/html, которую вы указали как корневой каталог в блоке сервера Nginx.
./nginx-conf:/etc/nginx/conf.d: Это позволит подключить папку конфигурации Nginx на хосте к соответствующему каталогу в контейнере, гарантируя, что любые изменения, вносимые в файлы на хосте, будут отражены на хосте.certbot-etc:/etc/letsencrypt: Это установит сертификаты и ключи Let's Encrypt для вашего домена в соответствующий каталог контейнера.
Вы также добавили этот контейнер в сеть приложений.
Наконец, под определением веб-сервера добавьте окончательное определение службы CertBot. Замените указанные здесь адрес электронной почты и доменное имя своими данными:
certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - wordpress:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
Это определение указывает Compose извлечь образ certbot/certbot из Docker Hub. Он также использует именованные тома для совместного использования ресурсов с контейнером Nginx, включая сертификаты доменов и ключи в certbot-etc, а также код приложения в WordPress. Опять же, вы использовали depend_on, чтобы указать, что контейнер certbot должен запускаться после запуска службы веб-сервера. Вы также добавили параметр команды, который задаёт подкоманду для запуска с командой certbot по умолчанию для контейнера. Подкоманда certonly получает сертификат со следующими параметрами:
--webroot: Это указывает Certbot использовать плагин webroot для размещения файлов в папке webroot для аутентификации. Плагин использует метод аутентификации HTTP-01, который использует HTTP-запрос для подтверждения того, что Certbot может получить доступ к ресурсам сервера, отвечающего на заданное доменное имя.--webroot-path: Здесь указывается путь к каталогу webroot.--электронная почта: Желаемый адрес электронной почты для регистрации и восстановления.--согласиться: Это означает, что вы согласны с Общим соглашением ACME.--no-eff-email: Это сообщает Certbot, что вы не хотите предоставлять доступ к своей электронной почте Electronic Frontier Foundation (EFF). Удалите это, если хотите.--постановка: Это сообщает Certbot, что вы хотите использовать тестовую среду Let's Encrypt для получения тестовых сертификатов. Использование этой опции позволяет протестировать параметры конфигурации и избежать потенциальных ограничений на количество запросов доменов. Подробнее об этих ограничениях см. в документации по ограничениям скорости Let's Encrypt.-д: Здесь вы можете указать доменные имена, которые вы хотите применить к своему запросу. В данном случае вы указали your_domain и www.your_domain. Обязательно замените их на свой домен.
Ниже определения службы certbot добавьте определения вашей сети и тома:
... volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
Ваш ключ тома верхнего уровня определяет тома certbot-etc, wordpress и dbdata. Когда Docker создаёт тома, их содержимое сохраняется в каталоге /var/lib/docker/volumes/ в файловой системе хоста, управляемом Docker. Содержимое каждого тома затем монтируется из этого каталога в любой контейнер, использующий этот том. Это позволяет контейнерам совместно использовать код и данные.
Пользовательская сеть мостов обеспечивает взаимодействие между контейнерами, поскольку они находятся на том же хосте, что и демон Docker. Это упрощает трафик и взаимодействие внутри приложения, поскольку открывает все порты между контейнерами в одной сети мостов, не открывая ни один из портов для внешнего мира. Таким образом, контейнеры базы данных, WordPress и веб-сервера могут взаимодействовать друг с другом, и вам нужно открыть только порт 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@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
Сохраните и закройте файл после завершения редактирования. После того, как определения служб готовы, вы готовы к запуску контейнеров и тестированию запросов на сертификаты.
Шаг 4 — Получите SSL-сертификаты и учетные данные
Запустите контейнеры с помощью команды docker-compose up, которая создаст и запустит контейнеры в указанном вами порядке. Если добавить флаг -d, команда запустит контейнеры db, WordPress и webserver в фоновом режиме:
docker-compose up -dСледующий вывод подтверждает, что ваша служба была создана:
Output
Creating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot ... doneПроверьте состояние ваших сервисов с помощью docker-compose ps:
docker-compose psПосле завершения ваши службы базы данных, WordPress и веб-сервера будут запущены, а контейнер certbot завершит работу с сообщением о статусе 0:
Output
Name Command State Ports
-------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcpЕсли в столбце «Состояние» для служб базы данных, WordPress или веб-сервера есть какие-либо значения, отличные от указанных выше, или статус выхода, отличный от 0, для контейнера certbot, вам, возможно, потребуется проверить журналы служб с помощью команды docker-compose logs:
docker-compose logs service_nameТеперь вы можете проверить, что ваши сертификаты установлены в контейнер веб-сервера с помощью docker-compose exec:
docker-compose exec webserver ls -la /etc/letsencrypt/liveПри успешном выполнении запросов на сертификат вывод кода будет следующим:
Output
total 16
drwx------ 3 root root 4096 May 10 15:45 .
drwxr-xr-x 9 root root 4096 May 10 15:45 ..
-rw-r--r-- 1 root root 740 May 10 15:45 README
drwxr-xr-x 2 root root 4096 May 10 15:45 your_domainТеперь, когда вы уверены, что ваш запрос выполнен успешно, вы можете отредактировать определение службы certbot, удалив --staging.
Откройте docker-compose.yml:
nano docker-compose.ymlНайдите часть файла с определением службы certbot и замените –staging в параметре команды на –force-renewal, который сообщает Certbot, что вы хотите запросить новый сертификат с теми же доменами. Сертификат обновляется под определением службы certbot с помощью переменной:
...
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- wordpress:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...Теперь вы можете запустить docker-compose для пересоздания контейнера certbot. Также добавьте опцию --no-deps, чтобы Compose мог пропустить запуск службы веб-сервера, поскольку она уже запущена:
docker-compose up --force-recreate --no-deps certbotСледующий вывод означает, что ваш запрос на сертификат был успешным:
Output Recreating certbot ... done Attaching to certbot certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log certbot | Plugins selected: Authenticator webroot, Installer None certbot | Renewing an existing certificate certbot | Performing the following challenges: certbot | http-01 challenge for your_domain certbot | http-01 challenge for www.your_domain certbot | Using the webroot path /var/www/html for all unmatched domains. certbot | Waiting for verification... certbot | Cleaning up challenges certbot | IMPORTANT NOTES: certbot | - Congratulations! Your certificate and chain have been saved at: certbot | /etc/letsencrypt/live/your_domain/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/your_domain/privkey.pem certbot | Your cert will expire on 2019-08-08. To obtain a new or tweaked certbot | version of this certificate in the future, simply run certbot certbot | again. To non-interactively renew *all* of your certificates, run certbot | "certbot renew" certbot | - Your account credentials have been saved in your Certbot certbot | configuration directory at /etc/letsencrypt. You should make a certbot | secure backup of this folder now. This configuration directory will certbot | also contain certificates and private keys obtained by Certbot so certbot | making regular backups of this folder is ideal. certbot | - If you like Certbot, please consider supporting our work by: certbot | certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0
Имея сертификаты на руках, вы можете изменить конфигурацию Nginx, включив SSL.
Шаг 5 — Измените конфигурацию веб-сервера и определение службы
Включение SSL в конфигурации Nginx включает добавление перенаправления с HTTP на HTTPS, указание расположения SSL-сертификата и ключей, а также добавление параметров безопасности и заголовков. Поскольку вы хотите перестроить службу веб-сервера, включив эти дополнения, вы можете остановить её сейчас:
docker-compose stop webserverПеред изменением файла конфигурации получите рекомендуемый параметр безопасности Nginx от Certbot с помощью curl:
curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.confЭта команда сохраняет эти параметры в файле options-ssl-nginx.conf, расположенном в каталоге nginx-conf.
Затем удалите созданный ранее файл конфигурации Nginx:
rm nginx-conf/nginx.confСоздайте и откройте еще одну версию файла:
nano nginx-conf/nginx.confДобавьте в файл следующий код для перенаправления HTTP на HTTPS и добавьте учётные данные, протоколы и заголовки безопасности SSL. Не забудьте заменить your_domain на свой домен:
server { listen 80; listen [::]:80; server_name your_domain www.your_domain; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { rewrite ^ https://$host$request_uri? permanent; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name your_domain www.your_domain; index index.php index.html index.htm; root /var/www/html; server_tokens off; ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem; include /etc/nginx/conf.d/options-ssl-nginx.conf; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # enable strict transport security only if you understand the implications location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass wordpress:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location ~ /\.ht { deny all; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; allow all; } location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; } }
Блок HTTP-сервера определяет корневой каталог веб-сайта для запросов на продление сертификатов Certbot в каталоге .well-known/acme-challenge. Он также включает директиву rewrite, которая перенаправляет 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 (HSTS) — включайте его только в том случае, если вы понимаете принципы его работы и оценили функционал предварительной загрузки.
Директивы root и directory также находятся в этом блоке, как и остальные блоки местоположений, специфичные для WordPress, которые обсуждались в Шаге 1. После завершения редактирования сохраните и закройте файл.
Перед повторным созданием службы веб-сервера необходимо добавить сопоставление порта 443 к определению службы веб-сервера.
Откройте файл docker-compose.yml:
nano docker-compose.ymlВ определении службы веб-сервера добавьте следующее сопоставление портов:
...
webserver:
depends_on:
- wordpress
image: nginx:1.15.12-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- app-networkВот полный файл docker-compose.yml после редактирования:
version: '3' services: db: image: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network wordpress: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: wordpress restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - wordpress:/var/www/html networks: - app-network webserver: depends_on: - wordpress image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - wordpress:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - wordpress:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain volumes: certbot-etc: wordpress: dbdata: networks: app-network: driver: bridge
Сохраните и закройте файл после завершения редактирования.
Пересоздайте службу веб-сервера:
docker-compose up -d --force-recreate --no-deps webserverПроверьте свои сервисы с помощью docker-compose ps:
docker-compose psВывод должен показать, что службы базы данных, WordPress и веб-сервера работают:
Output
Name Command State Ports
----------------------------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
db docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress docker-entrypoint.sh php-fpm Up 9000/tcpПосле запуска контейнеров вы можете завершить установку WordPress через веб-интерфейс.
Шаг 6 — Завершите установку через веб-интерфейс.
Пока ваши контейнеры запущены, завершите установку через веб-интерфейс WordPress.
В веб-браузере перейдите на домен вашего сервера. Не забудьте заменить your_domain на имя вашего домена:
https://your_domainВыберите нужный вам язык:
После нажатия кнопки “Продолжить” вы перейдете на главную страницу настроек, где вам нужно будет выбрать название сайта и имя пользователя. Рекомендуется выбрать запоминающееся имя пользователя (вместо «admin») и надежный пароль. Вы можете использовать пароль, автоматически сгенерированный WordPress, или создать свой собственный. Наконец, вам нужно будет ввести свой адрес электронной почты и решить, хотите ли вы запретить поисковым системам индексировать ваш сайт:
Нажав «Установить WordPress» внизу страницы, вы будете перенаправлены на страницу запроса на вход в систему:
После входа в систему вы получите доступ к панели администратора WordPress:
После завершения установки WordPress вы можете предпринять шаги для обеспечения автоматического продления ваших SSL-сертификатов.
Шаг 7 – Продление сертификатов
Сертификаты Let's Encrypt действительны в течение 90 дней. Вы можете настроить автоматическое продление, чтобы гарантировать их бессрочность. Один из способов сделать это — создать cron-задание. В примере ниже вы создаёте cron-задание для периодического запуска скрипта, который обновляет ваши сертификаты и перезагружает конфигурацию Nginx.
Сначала откройте скрипт под названием ssl_renew.sh:
nano 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: запускает контейнер certbot и переопределяет команду, указанную в определении службы certbot. Вместо подкоманды certonly используется подкоманда renew, которая обновляет сертификаты, срок действия которых подходит к концу. Также имеется опция --dry-run для тестирования вашего скрипта. docker-compose kill: Это отправит сигнал SIGHUP контейнеру веб-сервера для перезагрузки конфигурации Nginx.
Затем система запускает docker prune для удаления всех неиспользуемых контейнеров и образов.
После завершения редактирования файла закройте его. Сделайте его исполняемым с помощью следующей команды:
chmod +x ssl_renew.shЗатем откройте корневой файл crontab, чтобы запустить скрипт обновления с указанным интервалом времени:
sudo crontab -eЕсли вы впервые редактируете этот файл, вам будет предложено выбрать редактора:
Outputno crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/nano <---- easiest 2. /usr/bin/vim.basic 3. /usr/bin/vim.tiny 4. /bin/ed Choose 1-4 [1]: ...
В конец этого файла добавьте следующую строку:
...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1Это устанавливает интервал выполнения задания каждые пять минут, чтобы вы могли проверить, сработал ли ваш запрос на продление так, как вы планировали. Для записи соответствующих выходных данных задания создаётся файл журнала cron.log.
Через пять минут проверьте cron.log, чтобы убедиться в успешности запроса на расширение:
tail -f /var/log/cron.logСледующий вывод подтверждает успешное расширение:
Output- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/your_domain/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Для выхода нажмите CTRL+C в терминале.
Вы можете изменить файл crontab, чтобы задать ежедневный интервал. Например, чтобы запускать скрипт каждый день в полдень, измените последнюю строку файла следующим образом:
...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1Вам также следует удалить опцию --dry-run из вашего скрипта ssl_renew.sh:
#!/bin/bash COMPOSE="/usr/local/bin/docker-compose --no-ansi" DOCKER="/usr/bin/docker" cd /home/sammy/wordpress/ $COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af
Задание cron гарантирует, что ваши сертификаты Let's Encrypt не истекут, обновляя их по мере необходимости. Вы также можете настроить ротацию журналов с помощью инструмента Logrotate в Ubuntu 22.04 / 20.04 для ротации и сжатия файлов журналов.
Результат
В этом руководстве вы использовали Docker Compose для создания установки WordPress с веб-сервером Nginx. В рамках этого рабочего процесса вы получили TLS/SSL-сертификаты для домена, который хотите связать с вашим сайтом WordPress. Кроме того, вы создали cron-задание для обновления этих сертификатов по мере необходимости.













