I am struggling to retrieve the client IP address with Nginx in a docker compose project. Here’s a simplified version:
services:
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
networks:
- public
networks:
public:
Now I’ll simplify the nginx.conf:
http {
set_real_ip_from 172.17.0.0/16; # That's the public network's subnet.
real_ip_header X-Forwarded-For;
real_ip_recursive on;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; sendfile on;
server {
listen 80;
listen 443 ssl;
server_name example.com;
location / {
# ...
}
}
}
If I curl
my domain, let’s say example.com:
curl example.com
# logs
172.17.0.1 - - [02/Jul/2024:12:00:00 +0000] "GET / HTTP/1.1" 200 10 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" "-"
The log shows the current network Gateway IP in place of $remote_addr
, while $http_x_forwarded_for
is -
.
But if I curl
the server IP, let’s say 1.2.3.4:
curl 1.2.3.4
# logs
9.8.7.6 - - [02/Jul/2024:12:00:00 +0000] "GET / HTTP/1.1" 200 10 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" "-"
The log shows the right IP (my IP, let’s say 9.8.7.6), but the $http_x_forwarded_for
remains -
.
How can I capture the real client IP when resolving the domain name? Is there some options I should add to me docker network?