I run a django app via gunicorn, supervisor and nginx as reverse proxy and struggle to make my gunicorn access log show the actual ip instead of 127.0.0.1:
Log entries look like this at the moment:
127.0.0.1 - - [09/Sep/2014:15:46:52] "GET /admin/ HTTP/1.0" ...
supervisord.conf
[program:gunicorn]
command=/opt/middleware/bin/gunicorn --chdir /opt/middleware -c /opt/middleware/gunicorn_conf.py middleware.wsgi:application
stdout_logfile=/var/log/middleware/gunicorn.log
gunicorn_conf.py
#!python
from os import environ
from gevent import monkey
import multiprocessing
monkey.patch_all()
bind = "0.0.0.0:9000"
x_forwarded_for_header = "X-Real-IP"
policy_server = False
worker_class = "socketio.sgunicorn.GeventSocketIOWorker"
accesslog = '-'
my nginx module conf
server {
listen 80;
root /opt/middleware;
index index.html index.htm;
client_max_body_size 200M;
server_name _;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
real_ip_header X-Real-IP;
}
}
I tried all sorts of combinations in the location {} block, but can't see that it makes any difference. Any hint appreciated.
Nginx and Gunicorn work togetherGunicorn translates requests which it gets from Nginx into a format which your web application can handle, and makes sure that your code is executed when needed. They make a great team! Each can do something, which the other can't.
Gunicorn implements the Web Server Gateway Interface (WSGI), which is a standard interface between web server software and web applications. Nginx is a web server. It's the public handler, more formally called the reverse proxy, for incoming requests and scales to thousands of simultaneous connections.
Nginx Configuration Although there are many HTTP proxies available, we strongly advise that you use Nginx. If you choose another proxy server you need to make sure that it buffers slow clients when you use default Gunicorn workers. Without this buffering Gunicorn will be easily susceptible to denial-of-service attacks.
gunicorn-proxy is a Docker turnkey reverse proxy for gunicorn. To use it you only need to set one piece of configuration—The hostname and port of your gunicorn server.
The problem is that you need to configure gunicorn
's logging, because it will (by default) not display any custom headers.
From the documentation, we find out that the default access log format is controlled by access_log_format
and is set to the following:
"%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
where:
h
is the remote addressl
is -
(not used)u
is -
(not used, reserved)t
is the time stampr
is the status lines
is the status of the requestb
is length of responsef
is referrera
is user agentYou can also customize it with the following extra variables that are not used by default:
T
- request time (in seconds)D
- request time (in microseconds)p
- the process id{Header}i
- request header (custom){Response}o
- response header (custom)To gunicorn
, all requests are coming from nginx so it will display that as the remote IP. To get it to log any custom headers (what you are sending from nginx
) you'll need to adjust this parameter and add the appropriate variables, in your case you would set it to the following:
%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" "%({X-Real-IP}i)s"
Note that headers containing -
should be referred to here by replacing -
with _
, thus X-Forwarded-For
becomes %({X_Forwarded_For}i)s
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With