Запуск Discourse и WordPress (Docker) на одном VPS с использованием Nginx в качестве обратного прокси

Введение

По умолчанию установка Discourse в режиме «standalone» привязывается к портам 80 и 443. Чтобы разместить на том же сервере другое приложение, например WordPress, необходимо перенастроить Discourse так, чтобы он слушал внутренний порт, а также использовать Nginx на уровне хоста в качестве обратного прокси для управления трафиком и SSL-сертификатами.


1. Обзор архитектуры

  • Nginx на хосте: Основной шлюз, прослушивающий порты 80 и 443. Он обрабатывает завершение SSL и маршрутизирует запросы в соответствующий контейнер на основе server_name.

  • Контейнер Discourse: Перенастроен для прослушивания адреса localhost:8080.

  • Контейнер WordPress: Управляется через Docker Compose, прослушивает адрес localhost:8081.


2. Этап A: Перенастройка Discourse

Измените файл /var/discourse/containers/app.yml, чтобы освободить публичные порты:

  1. Измените сопоставление портов:

    YAML

    expose:
      - "8080:80"   # Сопоставляет порт хоста 8080 с портом контейнера 80
    
    
  2. Отключите внутренний SSL: Закомментируйте шаблоны SSL и Let’s Encrypt:

    YAML

    templates:
      - "templates/postgres.template.yml"
      - "templates/redis.template.yml"
      - "templates/web.template.yml"
      # - "templates/web.ssl.template.yml"
      # - "templates/web.letsencrypt.ssl.template.yml"
    
    
  3. Пересоберите: Выполните команду ./launcher rebuild app.


3. Этап B: Развертывание WordPress через Docker Compose

Организуйте свой сайт WordPress в отдельной директории. Убедитесь, что том базы данных является постоянным, чтобы предотвратить потерю данных.

YAML

services:
  db:
    image: mariadb:10.11
    environment:
      MYSQL_ROOT_PASSWORD: 'ваш_надежный_пароль'
    volumes:
      - ./mysql_data:/var/lib/mysql
  wordpress:
    image: wordpress:latest
    ports:
      - "8081:80"
    volumes:
      - .:/var/www/html


4. Этап C: Финальная конфигурация Nginx (SSL и порт 443)

Профессиональная настройка в 2025 году требует полной поддержки HTTPS и HTTP/2. После установки Nginx на хосте (sudo apt install nginx) создайте конфигурацию для ваших доменов.

Полезный совет: Выполните sudo certbot --nginx для автоматической генерации блоков SSL, но убедитесь, что они включают следующие заголовки прокси, чтобы Discourse работал корректно.

Nginx

server {
    listen 443 ssl http2;
    server_name discourse.com;

    # SSL-сертификаты от Certbot
    ssl_certificate /etc/letsencrypt/live/discourse.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/discourse.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        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; # Критично для определения HTTPS в Discourse
    }
}


5. Извлеченные уроки и лучшие практики

  • Учетные данные базы данных: Если ваши пароли содержат специальные символы, такие как & или ?, всегда заключайте их в одинарные кавычки ' ' в файлах конфигурации и командной строке, чтобы избежать ошибок интерпретации оболочкой.

  • Права доступа к файлам: Контейнеры WordPress работают от имени пользователя www-data (UID 33). Если вы загружаете или распаковываете файлы от имени root, необходимо выполнить chown -R 33:33 ., чтобы избежать ошибок «500 Internal Server Error».

  • Настройки Cloudflare: При использовании SSL-сертификата на сервере (Let’s Encrypt) установите режим SSL/TLS в Cloudflare на Full (Strict). Это предотвратит цикл «Too Many Redirects», часто вызываемый режимом «Flexible».

  • Постоянные тома: Никогда не выполняйте docker compose down или rebuild, не убедившись, что файлы вашей базы данных хранятся в постоянном томе (например, ./mysql_data).


Заключение: Отделение ваших приложений от портов 80/443 с помощью обратного прокси — это наиболее масштабируемый способ управления VPS с несколькими сайтами. Это позволяет централизованно управлять SSL и упрощает отладку через логи Nginx на уровне хоста.

2 лайка