• База знань
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

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

Пошаговый гайд по установке WordPress через Docker Compose с настройкой Nginx, MySQL и автоматическим получением 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.

Кнопка InstallWordPress

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

Сообщение исталятора

Налаштування автоматичного оновлення сертифікатів

Строк дії сертифікатів закінчується через три місяці. Для їх автоматичного подовження слід виконати певні дії.

Відкриємо файл 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
navigate
go
exit
Дякуємо, що обираєте FREEhost.UA