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

Зміст:
- Виконання попередніх умов
- Налаштування веб-серверу
- Налаштування змінних
- Визначення служб у файлі docker-compose.yml
- Отримання SSL-сертифікатів
- Коригування конфігурації Nginx та визначення служби з урахуванням активованого SSL
- Завершальна стадія
- Налаштування автоматичного оновлення сертифікатів
Для роботи CMS WordPress зазвичай використовується стек веб-технологій із веб-сервером (Apache або Nginx), PHP та СУБД. Традиційне розгортання та налаштування такого середовища вручну потребує часу й уважної конфігурації кожного компонента.
Одним із зручних підходів до запуску WordPress є використання Docker та Docker Compose, які дозволяють швидко підготувати ізольоване контейнерне середовище, керувати залежностями та відтворювати конфігурацію на різних системах. У цій статті розглянемо приклад створення та налаштування середовища для WordPress за допомогою Docker Compose.
Виконання попередніх умов
Перед початком налаштувань слід попередньо виконати ряд базових умов. Наведемо їх:
-
VPS-сервер із ОС Linux та користувач з повноваженнямиsudo, не root;
-
Увімкнений брандмауер;
-
Розгорнуті та активовані Docker та Docker Compose;
-
Зареєстрований домен;
-
Наявність на сервері налаштованих DNS записів типу A для вашого домену
У нашому випадку це буде сервер із ОС Ubuntu 18.04. Ім’я користувача – 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 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: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 certbot
Тут опція --no-deps виключає повторний запуск webserver.
Вихід команди повинен бути наступним:
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.

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

Налаштування автоматичного оновлення сертифікатів
Строк дії сертифікатів закінчується через три місяці. Для їх автоматичного подовження слід виконати певні дії.
Відкриємо файл 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