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:
- HAProxy is actually sending the PROXY protocol to the Discourse container.
- 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.