Создать сайт с помощью контейнеров на UBUNTU 24.04.

Для сайта потребуется создать несколько контейнеров. Для запуска сайта на домене и публичном сервере (через SSH) лучше всего сразу использовать связку Docker + WordPress + Nginx + Let’s Encrypt (Certbot). Это позволит сайту работать по безопасному протоколу HTTPS. Подключитесь к вашему серверу по SSH (ssh root@ip_сервера) и выполните обновление системы:

sudo apt update && sudo apt upgrade -y

Для установки Docker потребуется несколько вспомогательных пакетов:

sudo apt install curl software-properties-common ca-certificates apt-transport-https -y

Для защиты системы от поддельных пакетов нужно добавить GPG-ключ официального репозитория. Этот ключ используется для проверки подписи пакетов и подтверждает, что они действительно опубликованы разработчиками Docker, а не изменены сторонними источниками

wget -O- https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor | sudo tee /etc/apt/keyrings/docker.gpg > /dev/null

Следующий шаг — подключение официального репозитория Docker. Это нужно, чтобы система могла получать актуальные версии пакетов напрямую от разработчиков. В стандартных репозиториях Ubuntu обычно находятся устаревшие сборки, поэтому установка через официальный источник — более надежный вариант:

echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Устанавливаем Docker и Docker Compose:

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Проверим корректность установки:

docker compose version

Теперь нужно создать конфигурационные файлы. Папки для файлов создадим в папке opt:

mkdir -p /opt/wordpress-site/nginx && cd /opt/wordpress-site

Cоздадим файл:

nano docker-compose.yml

Ниже составлен этот файл, измените свои данные container_name, MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD. Учитывайте пробелы в начале строк, есть строки без пробелов, строки с двумя пробелами, с 4 пробелами, 6 пробелами.

Параметр mem_limit указывает какой объем памяти использовать, в нашем примере для базы данных 512 m для сайта 256 m, для nginx 128 m

Лучше чем копировать можно открыть текстовый файл по адресу, изменить Ваши данные и расширение файла, потом скопировать:

services:
  db:
    image: mysql:8.0
    container_name: wpdb
    restart: always
    mem_limit: 512m
    environment:
      MYSQL_ROOT_PASSWORD: root-pass
      MYSQL_DATABASE: bazawp
      MYSQL_USER: bd-uzer
      MYSQL_PASSWORD: bd-pass
    volumes:
      - db_data:/var/lib/mysql
  wordpress:
    image: wordpress:latest
    container_name: wordpress
    restart: always
    mem_limit: 256m
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: bazawp
      WORDPRESS_DB_USER: bd-uzer
      WORDPRESS_DB_PASSWORD: bd-pass
    volumes:
      - wp_data:/var/www/html
    depends_on:
      - db
  nginx:
    image: nginx:alpine
    container_name: nginx_proxy
    restart: always
    mem_limit: 128m
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - certbot_certs:/etc/letsencrypt
      - certbot_www:/var/www/certbot
    depends_on:
      - wordpress
  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot_certs:/etc/letsencrypt
      - certbot_www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
  db_backup:
    image: databack/mysql-backup:latest
    container_name: wpdb_backup
    restart: always
    environment:
      DB_SERVER: db
      DB_PORT: 3306
      DB_USER: root
      DB_PASS: root-pass
      DB_NAMES: bazawp
      CRON_TIME: "0 3 * * *"
      CLEANUP_OLDER_THAN: 14
    volumes:
      - backup_data:/db
    depends_on:
      - db
volumes:
  db_data:
  wp_data:
  certbot_certs:
  certbot_www:
  backup_data:

Сохраните docker-compose.yml (Ctrl+O, Enter, Ctrl+X) в редакторе и будем редактировать еще.

nano nginx/default.conf

Создайте файл первичной конфигурации, чтобы подтвердить права на ваш домен. Измените yourdomen.com на Ваш домен. Можно посмотреть этот файл в текстовом формате и скопировать

server {
    listen 80;
    server_name yourdomen.com www.yourdomen.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        proxy_pass http://wordpress:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Сохраните файл default.conf (нажмите Ctrl+O, затем Enter, и для выхода Ctrl+X).

Запускаем все контейнеры в фоновом режиме.

docker compose up -d

После того как контейнеры успешно стартовали, Nginx готов принимать запросы проверки. Теперь можно вызывать Certbot. Запускаем Certbot внутри контейнера для выпуска сертификата. Поменяйте yourdomen.com на ваш домен.

docker compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot -d yourdomen.com -d www.yourdomen.com
  • —rm — автоматически удалит временный контейнер Certbot после того, как он выполнит свою работу, чтобы не забивать память сервера.
  • certonly — команда только на выпуск сертификата (без автоматической настройки Nginx, так как мы настроим его сами).
  • -d yourdomen.com -d www.yourdomen.com — запрос сертификата сразу для основного домена и поддомена с www.

Let’s Encrypt выпустит ключи и сохранит их на сервере. Теперь нам нужно перенастроить Nginx на полноценную работу по безопасному протоколу HTTPS (порт 443).

Редактируем файл default.conf

nano nginx/default.conf

Скопируйте код ниже и полностью вставьте в редактируемый файл

server {
    listen 80;
    server_name yourdomen.com www.yourdomen.com; # Замените на ваш домен

    # Оставляем путь для автоматического продления сертификатов Certbot
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    
    # Постоянный редирект со старого HTTP на безопасный HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name yourdomen.com www.yourdomen.com; # Замените на ваш домен

    # Пути к полученным SSL-сертификатам (замените yourdomen.com на ваше имя домена!)
    ssl_certificate /etc/letsencrypt/live/yourdomen.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomen.com/privkey.pem;

    
    # Настройки безопасности SSL
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Проксирование трафика в контейнер WordPress
    location / {
        proxy_pass http://wordpress:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Сохраните файл default.conf (нажмите Ctrl + O, затем Enter, а для выхода из редактора — Ctrl + X).

Чтобы изменения вступили в силу и Nginx переключил сайт на безопасный протокол HTTPS, его необходимо перезапустить. Добавьте в самый конец статьи эту финальную команду

docker compose exec nginx_proxy nginx -t && docker compose exec nginx_proxy nginx -s reload

Если все прошло без ошибок, то в браузере Вы сможете зайти на сайт. В дополнение напишу команды для управления контейнерами.

Посмотреть, какие контейнеры работают прямо сейчас и сколько памяти они занимают

docker compose ps

Посмотреть подробную статистику нагрузки на сервер в реальном времени

docker stats

Помогает проверить, укладываются ли контейнеры в заданные нами лимиты памяти (mem_limit). Чтобы выйти из этого режима, нажмите Ctrl + C.

Полностью остановить работу сайта и всех его контейнеров

docker compose down

Эта команда безопасно останавливает и выключает все контейнеры. При этом все ваши данные (статьи, картинки, база данных) не удалятся, так как они надежно сохранены в томах (volumes).

Снова запустить ранее остановленный сайт

docker compose up -d
Прокрутить вверх