Как я могу напрямую изменить конфигурацию Nginx внутри discourse/docker?

Я хотел бы изменить конфигурацию Nginx/Docker, так как моя установка Discourse находится за HAProxy. Проблема заключается в следующем:
Все IP-адреса, подключающиеся к моей установке Discourse, отображаются как IP-адрес HAProxy.
Мне нужно добавить следующие строки в конфигурационный файл Nginx:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

…чтобы передать публичные IP-адреса, подключающиеся к моей установке Discourse, в Nginx.
Спасибо за помощь.

Скорее всего, вам не стоит использовать только:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

Это верно только если оба следующих условия выполняются:

  1. HAProxy действительно отправляет протокол PROXY в контейнер Discourse.
  2. Nginx внутри контейнера Discourse видит HAProxy как 127.0.0.1.

Во многих конфигурациях HAProxy → Discourse Docker проще и чаще используется заголовок X-Forwarded-For, а не протокол PROXY.

Для HAProxy убедитесь, что он отправляет заголовок с пересланным IP:

defaults
    mode http
    option httplog
    option forwardfor

или в бэкенде:

backend be_discourse
    option forwardfor
    server app 127.0.0.1:8080 check

Затем в конфигурации контейнера Discourse внесите изменения Nginx для реального IP через app.yml. Не редактируйте файлы напрямую внутри запущенного контейнера, так как они будут потеряны при пересборке.

Добавьте что-то вроде этого в /var/discourse/containers/app.yml в существующий раздел run::

run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 127.0.0.1;
        # настройте это под фактический диапазон сети/моста Docker, с которого подключается HAProxy
        set_real_ip_from 172.17.0.0/16;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        types {

Затем пересоберите:

cd /var/discourse
./launcher rebuild app

Возможно, вам потребуется скорректировать set_real_ip_from, чтобы он соответствовал фактическому исходному IP/диапазону, который Nginx внутри контейнера Discourse видит при подключении HAProxy. В Docker это часто не 127.0.0.1; это может быть адрес моста Docker, например 172.17.0.1, или диапазон пользовательской сети Docker.

Если вы действительно хотите использовать протокол PROXY, HAProxy должен явно его отправлять:

backend be_discourse
    server app 127.0.0.1:8080 check send-proxy

и Nginx должен слушать с параметром proxy_protocol, а не просто читать real_ip_header proxy_protocol:

run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "listen 80;"
      to: "listen 80 proxy_protocol;"

  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 127.0.0.1;
        set_real_ip_from 172.17.0.0/16;
        real_ip_header proxy_protocol;
        types {

Важное исправление: одного real_ip_header proxy_protocol недостаточно. Nginx также нуждается в директиве listen 80 proxy_protocol;, а HAProxy — в send-proxy. В противном случае используйте X-Forwarded-For, что является стандартной настройкой для HTTP-режима HAProxy. В HAProxy option forwardfor — это стандартный способ добавления заголовка IP клиента X-Forwarded-For. При использовании протокола PROXY в Nginx директива listen должна включать proxy_protocol, прежде чем real_ip_header proxy_protocol сможет работать.

Итак, краткая версия:

  • Используйте X-Forwarded-For, если у вас нет конкретной причины использовать протокол PROXY.
  • Не смешивайте эти два режима.
  • Если HAProxy не использует send-proxy, то real_ip_header proxy_protocol работать не будет.
  • Если используете Discourse Docker, вносите изменения в app.yml, а не напрямую внутри запущенного контейнера.