如何在 discourse/docker 中直接修改 Nginx 配置?

我想修改 Nginx/Docker 配置,因为我的 Discourse 安装在 HAProxy 后面。我遇到的问题如下:

所有连接到我的 Discourse 安装的 IP 地址都显示为 HAProxy 的 IP 地址。

我需要在 Nginx 配置文件中添加以下行:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

…以便将连接到我的 Discourse 安装的公共 IP 地址传递给 Nginx。

感谢您的帮助。

你很可能应该只使用:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

仅当以下两个条件都满足时,上述配置才是正确的:

  1. HAProxy 实际上正在向 Discourse 容器发送 PROXY 协议。
  2. Discourse 容器内的 Nginx 将 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 容器配置中,通过 app.yml 持久化 Nginx 的真实 IP 更改。不要直接编辑运行中容器内的文件,因为重建后这些更改将会丢失。

/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;
        # 根据 HAProxy 连接的实际 Docker 网桥/网络范围进行调整
        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 以匹配 HAProxy 连接时,Discourse 容器内 Nginx 看到的实际源 IP/范围。在使用 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,这是 HAProxy HTTP 模式下的常规设置。在 HAProxy 中,option forwardfor 是添加 X-Forwarded-For 客户端 IP 标头的标准方式。在使用 Nginx PROXY 协议时,listen 指令必须包含 proxy_protocolreal_ip_header proxy_protocol 才能生效。

简而言之:

  • 除非你有特定理由使用 PROXY 协议,否则请使用 X-Forwarded-For
  • 不要混合使用这两种模式。
  • 如果 HAProxy 未使用 send-proxy,则 real_ip_header proxy_protocol 将无法工作。
  • 如果使用 Discourse Docker,请在 app.yml 中进行更改,而不是直接在运行中的容器内修改。