![](/img/trans.png)
[英]Nginx reverse-proxy for python app using docker-compose
[英]docker-compose an app behind a reverse-proxy that can also access external services
在本地服务器上,我启动了几个 gunicorn 实例,每个实例在一个独特的端口上运行不同的 web 应用程序作为对 internal.network 的 rest 的服务。 现在我想将每个 gunicorn 实例放在其自己的 nginx 反向代理服务器后面,以实现更好的负载平衡。
我决定尝试将每个(nginx、gunicorn)对部署在其自己的 Docker 容器中,仅将其唯一端口暴露给外界。 我知道端口转发很容易-例如“5555:80”。 但是,每个应用程序还访问外部服务,例如数据库,这些服务独立于 Docker 运行在同一主机上。
通过反复试验,我发现一个 Docker 容器只有当我以“docker run -.network=host ...”运行时才能访问外部服务(例如 MySQL,或 MongoDB)。 这具有让容器共享 host.network 的效果,但它也暴露了 gunicorn 打开的所有端口,这意味着它为客户端留下了绕过反向代理的方法。 虽然这一切都在 secure.network 上的本地服务器上运行,但这似乎不是一个好的安全实践,因为它使后端对拒绝服务攻击开放。
所以我想我想要两全其美 - 我希望每一对(代理,gunicorn)通过只有他们使用的 private.network 相互交谈,同时我将一个端口(例如“5555”)暴露给.network ,而在gunicorn下运行的web app仍然可以访问同一主机上的其他服务。
我的 nginx.conf 看起来像这样:
http {
upstream app {
server network1_app;
}
server {
location / {
proxy_pass http://app;
}
}
}
我的 docker-compose.yml 可能类似于:
version: "3"
services:
proxy:
image: nginx:alpine
networks:
- host
- network1
volumes:
./nginx.conf:/etc/nginx/nginx.conf:ro
app:
build: ./app
networks:
- network1
ports: "5555:80" # Do I have to associate this with the "host" network somehow?
networks:
network1:
然后部署这个
docker stack deploy network1 -c docker-compose.yml
我是在正确的道路上,还是我让它变得太复杂了? 为此根本不使用 Docker 会更直接吗? 相反,我可以为此创建名为 sockets 的名称。
如果可以的话,我喜欢使用 docker-compose,因为它封装了一些细节并使管理更容易(如果它有效)。 它还为安全漏洞留下了更少的表面。
在阅读了这个线程并进行了一些尝试和错误之后,我才发现问题在于主机 iptables 将请求丢弃到端口 22 (ssh) 以外的几乎任何地方。
例如:
$ docker run -it --rm --add-host host.docker.internal:xxx.xxx.xxx.xxx busybox telnet host.docker.internal 27017
超时。
但
$ docker run -it --rm --add-host host.docker.internal:xxx.xxx.xxx.xxx busybox telnet host.docker.internal 22
Connected to host.docker.internal
我可能可以通过 iptables 中的一个简单规则来克服这个问题:
-A INPUT -i docker0 -j ACCEPT
然后在我的 docker-compose.yaml 中添加一个部分:
extra-hosts:
- "host.docker.internal:xxx.xxx.xxx.xxx"
我暂时推迟,因为我的项目负责人让我等一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.