How can I modify the Nginx configuration directly within discourse/docker?

I would like to modify the Nginx/Docker configuration because my Discourse installation is behind HAProxy. The issue I am facing is as follows:
All IPs connecting to my Discourse installation appear as the HAProxy IP address.
I need to add the following lines to the Nginx configuration file:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

…in order to pass the public IPs connecting to my Discourse installation through to Nginx.
Thank you for your help.

You probably do not want only:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

That is only correct if both of these are true:

  1. HAProxy is actually sending the PROXY protocol to the Discourse container.
  2. Nginx inside the Discourse container sees HAProxy as 127.0.0.1.

In many HAProxy → Discourse Docker setups, the simpler and more common approach is to use X-Forwarded-For, not PROXY protocol.

For HAProxy, make sure it sends the forwarded IP header:

defaults
    mode http
    option httplog
    option forwardfor

or in the backend:

backend be_discourse
    option forwardfor
    server app 127.0.0.1:8080 check

Then in the Discourse container config, persist the Nginx real-IP changes through app.yml. Do not edit files directly inside the running container, because they will be lost on rebuild.

Add something like this to /var/discourse/containers/app.yml under the existing run: section:

run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 127.0.0.1;
        # adjust this to the actual Docker bridge/network range HAProxy connects from
        set_real_ip_from 172.17.0.0/16;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        types {

Then rebuild:

cd /var/discourse
./launcher rebuild app

You may need to adjust set_real_ip_from to match the actual source IP/range that Nginx inside the Discourse container sees when HAProxy connects to it. With Docker, this is often not 127.0.0.1; it may be a Docker bridge address such as 172.17.0.1 or a user-defined Docker network range.

If you really want to use the PROXY protocol instead, HAProxy must explicitly send it:

backend be_discourse
    server app 127.0.0.1:8080 check send-proxy

and Nginx must listen with proxy_protocol, not just read 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 {

The important correction is: real_ip_header proxy_protocol alone is incomplete. Nginx also needs listen 80 proxy_protocol;, and HAProxy needs send-proxy. Otherwise, use X-Forwarded-For, which is the usual HAProxy HTTP-mode setup. In HAProxy, option forwardfor is the standard way to add the X-Forwarded-For client IP header. With Nginx PROXY protocol, the listen directive must include proxy_protocol before real_ip_header proxy_protocol can work.

So the short version is:

  • Use X-Forwarded-For unless you have a specific reason to use PROXY protocol.
  • Do not mix the two modes.
  • If HAProxy is not using send-proxy, then real_ip_header proxy_protocol will not work.
  • If using Discourse Docker, make the change in app.yml, not directly inside the running container.