我有两个docker容器正在运行,一个是nginx作为80,443上的反向代理,它接受http和https请求并将它们传递给另一个容器,这是一个在端口8000上运行的Python Flask App容器。
如果我在主机上运行nginx而不是在容器中运行它,那么应用程序可以读取正确的客户端IP地址,但
如果我也在一个容器中运行nginx,它只显示docker0网络接口的ip地址到第二个容器中运行的烧瓶应用程序,无论实际的客户端ip是什么。
在Python Flask应用程序中,我使用以下代码:
ip = request.environ.get('HTTP_X_REAL_ip', request.remote_addr)
Docker-Compose文件:
mongo:
restart: always
image: mongo:latest
ports:
- '27017'
volumes:
- /opt/python/apps/myapp/PersistentDockerVolumes/mongo/data:/data/db/
redis:
restart: always
build: ./redis
command: ["redis-server", "/usr/local/etc/redis/redis.rb"]
ports:
- '6379'
myapp:
restart: always
build: ./myapp
command: ["gunicorn", "--config=gunicorn.py", "myapp:app"]
environment:
DEBIAN_FRONTEND: 'noninteractive'
PYTHONUNBUFFERED: 'true'
links:
- mongo
- redis
volumes:
- /opt/python/apps/myapp/logs/myapp/:/myapp/log/
ports:
- '8000'
nginx:
restart: always
build: ./nginx
command: ["nginx", "-g", "daemon off;"]
links:
- myapp
volumes:
- /opt/python/apps/myapp/logs/nginx:/etc/nginx/logs
volumes_from:
- myapp
ports:
- '80:80'
- '443:443'
在nginx配置中,我已经定义了一个代理传递给myapp:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
我尝试寻找解决方案,但它们都不适用于python flask应用程序。我的场景类似于this,但不同之处在于我对Flask而不是Jetty有解决方案,而且解决方案对Jetty非常具体。
另一个部分相似的线程是here,在这个线程中讨论的场景是nginx反向代理后面的nginx服务器,这也是不同的场景,我对运行停用iptables的docker持怀疑态度。