• База знаний
  • /
  • Блог
  • /
  • 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 и пользователь с полномочиямисудо, не корень;

  • Включен брандмауэр;

  • Развернутые и активированные 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.

Кнопка InstallWordPress

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

Повідомлення інсталятора

После ввода логина и пароля мы можем войти в панель управления 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
navigate
go
exit
Спасибо, что выбираете FREEhost.UA