Статья также доступна на украинском (перейти к просмотру).

Содержание:
- Выполнение предварительных условий
- Настройка веб-сервера
- Настройка переменных
- Определение служб в файле docker-compose.yml
- Получение SSL-сертификатов
- Коррекция конфигурации Nginx и определение службы с учетом активированного SSL
- Завершающая стадия
- Настройка автоматического обновления сертификатов
Для работы CMS WordPress обычно используется стек веб-технологий с веб-сервером (Apache или Nginx), PHP и СУБД. Традиционное развертывание и настройка такой среды вручную требует времени и внимательной конфигурации каждого компонента.
Одним из удобных подходов к запуску WordPress является использование Docker и Docker Compose, позволяющих быстро подготовить изолированную контейнерную среду, управлять зависимостями и воспроизводить конфигурацию на разных системах. В этой статье рассмотрим пример создания и настройки среды WordPress с помощью Docker Compose.
Выполнение предварительных условий
Перед началом настройки следует выполнить ряд базовых условий. Приведем их:
-
VPS-сервер с ОС Linux и пользователь с полномочиямисудо, не корень;
-
Включен брандмауэр;
-
Развернутые и активированные Docker та Docker Compose;
-
Зарегистрированный домен;
-
Наличие на сервере настроенных DNS записей типа А для вашего домена.
В нашем случае это будет test_wp. Имя домена wpsite.ua.
О том, как установить на сервер Docker compose читайте в нашей предыдущая статья
Проверить статус службы Docker можно с помощью следующей команды:
$ sudo systemctl status docker
Выход команды должен быть примерно таким:
? docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled) Active: active (running) since Tue 2026-02-03 14:40:47 EET; 9min ago TriggeredBy: ? docker.socket Docs: https://docs.docker.com Main PID: 1407860 (dockerd) Tasks: 9 Memory: 32.4M CPU: 850ms CGroup: /system.slice/docker.service ??1407860 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Следовательно, служба активирована.
На следующем этапе можно проверить реальную способность службы загружать шаблоны и запускать их в контейнере с помощью тестового шаблона .«Hello from Docker!».
$ sudo docker run hello-world
Выход будет следующим:
Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 17eec7bbc9d7: Pull complete ea52d2000f90: Download complete Digest: sha256:05813aedc15fb7b4d732e1be879d3252c1c9c25d885824f6295cab4538cb85cd Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly.
подтверждает, что ваша установка, по всей видимости, работает корректно.
Это говорит о том, что Docker Engine успешно запущен.
Проверить существующую версию Docker Compose можно с помощью следующей команды:
$ docker-compose --version
Выход:
docker-compose version 1.29.2, build 5becea4c
Это означает, что компонент установлен и готов к работе.
После этого мы поочередно выполним ряд следующих этапов:
-
Конфигурируем веб-сервер;
-
Настроим переменные программной среды;
-
Определим службы средствами Docker Compose;
-
Получим SSL-сертификаты;
-
Скорректируем конфигурацию Nginx и определение службы с учетом активированного SSL;
-
Получим доступ к панели WordPress через веб-интерфейс;
-
Настроим обновление сертификатов.
Настройка веб-сервера
Настройка заключается в включении в файл конфигурации Nginx серверных блоков для определения обработчиков запросов, а также блоков размещения location для перенаправления запросов сертификатов от клиента Certbot, обработки запросов статики и PHP
Создадим каталог проекта и перейдем к нему:
$ mkdir wordpress $ cd wordpress
Создадим каталог для хранения файла конфигурации Nginx:
$ mkdir nginx-conf
С помощью редактора внесем в файл конфигурации nginx.conf следующие данные:
$ nano nginx-conf/nginx.conf
server {
listen 80; //Определяет порт для прослушивания запросов
listen [::]:80;
server_name wpsite.ua www.wpsite.ua; //Объявляет имя сервера
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 для production”
Настройка переменных
С помощью переменных окружения можно обеспечить передачу значений конфиденциальных параметров в базы данных и контейнеры приложений во время выполнения.
Параметры будут храниться в файле .env:
$ nano .env MYSQL_ROOT_PASSWORD=root_pass //Пароль для root-пользователя MySQL MYSQL_USER=dbase_user //Имя пользователя БД для WordPress MYSQL_PASSWORD=dbase_pass //Пароль пользователя БД для WordPress
Установим текущую директорию в качестве Git-репозитория:
$ git init
Initialized empty Git repository in /home/test_wp/wordpress/.git/
Теперь все файлы директории будут копироваться в репозитории и Docker-шаблоны. Чтобы обезопасить себя от утечки конфиденциальной информации при использовании Git, следует добавить имя файла .env в следующие файлы:
$ nano .gitignore .env $ nano .dockerignore .env .git .dockerignore docker-compose.yml
Определение служб в файле docker-compose.yml
Услуги в представляют собой отдельные изолированные процессы или контейнеры, в которые будут запускаться определенные шаблоны. Их настройка определяет режимы работы этих процессов.
Откроем файл docker-compose.yml и пропишем в нем следующий код:
$ nano docker-compose.yml version: '3' services: db: //Определение службы 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: //Определение службы Nginx 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: //Определение службы 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 my@wpsite.ua --agree-tos --no-eff-email --staging -d wpsite.ua -d www.wpsite.ua volumes: //Определение тома certbot-etc: wordpress: dbdata: networks: //Определение сети app-network: driver: bridge
После сохранения файла можно запустить контейнеры.
Получение SSL-сертификатов
Запустим определенные нами службы в фоновом режиме с помощью следующей команды:
$ docker-compose up -d
На выходе получим:
Creating db ............ done Creating wordpress ..... done Creating webserver ..... done Creating certbot ..... done
Проверим статус служб:
$ docker-compose p
Результат должен быть примерно таким:
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 свидетельствует об успешном запуске служб. В столбце Command присутствует список нужных сертификатов.
Убедимся, что сертификаты имеются в webserver:
$ docker-compose exec webserver ls -la /etc/letsencrypt/live
На выходе получим:
total 16 drwx------ 3 root root 4096 Feb 06 18:30 . drwxr-xr-x 9 root root 4096 Feb 06 18:30 .. -rw-r--r-- 1 root root 740 Feb 06 18:30 README drwxr-xr-x 2 root root 4096 Feb 06 18:30 wpsite.ua
Следовательно, запросы сертификата были успешными.
Для того чтобы получить новый сертификат для доменов, следует сначала заменить опцию --staging на --force-renewal в определении службы certbot в файле docker-compose.yml. Соответствующий участок кода должен выглядеть следующим образом:
$ nano docker-compose.yml ... 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 my@wpsite.ua --agree-tos --no-eff-email --force-renewal -d wpsite.ua -d www.wpsite.ua ...
После сохранения внесенных изменений обновим контейнер:
$ docker-compose up --force-recreate --no-deps certbo
Здесь опция --no-deps исключает повторный запуск веб-сервер
Выход команды должен быть следующим:
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 wpsite.ua certbot | http-01 challenge for www.wpsite.ua 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/wpsite.ua/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/wpsite.ua/privkey.pem certbot | Your cert will expire on 2026-05-06. 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
Нам нужно будет внести следующие изменения в конфигурацию Nginx:
-
Обеспечить перенаправление HTTP на HTTPS;
-
Добавить заголовки и параметры безопасности;
-
Указать местоположение SSL-ключей и сертификата.
Предварительно получим опции безопасности от Certbot, которые будут храниться в файле options-ssl-nginx.conf:
$ 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
Удалите предыдущий файл конфигурации:
$ rm nginx-conf/nginx.conf
Внесем обновленный код в новый файл конфигурации:
server {
listen 80;
listen [::]:80;
server_name wpsite.ua www.wpsite.ua;
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 wpsite.ua www.wpsite.ua;
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/wpsite.ua/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wpsite.ua/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;
}
}
Сохраним внесенные изменения и закроем файл.
После этого изменим определение службы webserver в файле 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 up -d --force-recreate --no-deps webserver
Проверим список служб:
$ docker-compose ps
Результат должен быть следующим:
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
Теперь нам осталось завершить процесс развертывания CMS с помощью веб-интерфейса.
Завершающая стадия
Введем в адресной ленте браузера:
https://wpsite.ua
В появившемся окне выбираем язык.

После этого вводим свои учетные данные и жмем по кнопке Установить WordPress.

Якщо все гаразд, з’являється показане нижче повідомлення інсталятора.

После ввода логина и пароля мы можем войти в панель управления WordPress.
Настройка автоматического обновления сертификатов
Срок действия сертификатов заканчивается через три месяца. Для их автоматического продления следует выполнить определенные действия.
Откроем файл ssl_renew.sh и внесем в него следующий код:
$ nano ssl_renew.sh #!/bin/bash COMPOSE="/usr/local/bin/docker-compose --no-ansi" DOCKER="/usr/bin/docker" cd /home/sammy/wordpress/ $COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af
Сохраним внесенные изменения и закроем файл.
Далее выполним:
$ chmod +x ssl_renew.sh $ sudo crontab -e
Добавляем в конец файла crontab следующую строчку:
... 0 15 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1
Сохраним внесенные изменения и закроем файл.
В результате, сценарий для автоматического обновления сертификатов будет запускаться каждый день в 15 часов.
Техническое решение от Freehost.UA
Freehost предлагает VPS-хостинг, который подходит как для размещения сайтов WordPress, так и для построения собственной контейнерной инфраструктуры на базе Docker.
VPS-серверы можно использовать для подготовки шаблонов Docker-окружения с WordPress, базами данных и вспомогательными сервисами. При помощи Docker Compose | Portainer такие шаблоны легко хранить, управлять ими и повторно использовать — достаточно один раз подготовить рабочий стек и быстро развертывать его на новых проектах или серверах.
Такой подход упрощает администрирование, уменьшает время на запуск новых сайтов и позволяет поддерживать одинаковую конфигурацию среды на разных VPS.
Подписывайтесь на наш Telegram-канал https://t.me/freehostua, чтобы быть в курсе новых полезных материалов
Смотрите наш канал YouTube на https://www.youtube.com/freehostua.
Мы в чем ошиблись, или что-то пропустили?
Напишите об этом в комментариях, мы с удовольствием ответим и обсуждаем Ваши замечания и предложения.
|
Дата: 11.02.2026 Автор: Александр Ровник
|
|

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:
comments powered by Disqus