Nginx 在 Docker 中运行,反向代理到 Docker 外部的本地主机

Nginx 在 Docker 中运行,反向代理到 Docker 外部的本地主机

为了解决工作项目中一些操作上的愚蠢问题,我正在尝试:

  1. 运行服务 A 监听localhost:4001并运行服务 B 监听localhost:4002
  2. 在 Docker 容器内运行 Nginx;内部监听0.0.0.0:80
  3. 在主机系统上设置 Docker 监听 localhost:80,将请求转发到 Nginx 容器中的端口 80。
  4. 设置 Nginx 转发localhost:80/alocalhost:4001,并转发localhost:80/blocalhost:4002

我可以编写自己的nginx.conf文件,但出于操作和组织的原因,我只能在 Docker 内运行 Nginx。

但是,是否可以让运行在容器内的 Nginx 服务器将请求代理到环回设备主机系统

我正在尝试做的事情的图表:

                     ┌──────────────────┐
                     │                  │
                     │ My web browser   │─┐
                     └──────────────────┘ │
         ┌────────────────────────────────┼───────┐
         │                                │       │
         │      ┌──────────────────────┐  │       │
         │      │                      │← │       │
     ┌───┼──────│ Nginx (0.0.0.0:80)   │──┘       │
     │ ┌─┼──────│                      │          │
     │ │ │      └──────────────────────┘          │
     │ │ │                                        │
     │ │ │ Docker (localhost:80 -> 172.17.0.1:80) │
     │ │ └────────────────────────────────────────┘
     │ └────────────────────────────┐
     │                              │
    ↓│                             ↓│
 ┌───────────────────────────┐  ┌───────────────────────────┐
 │                           │  │                           │
 │ Daemon A (localhost:4001) │  │ Daemon B (localhost:4002) │
 └───────────────────────────┘  └───────────────────────────┘

答案1

根据设计,监听 或 的应用程序localhost只能127.0.0.1/8::1/128同一台机器上本地访问。或者严格地说,从同一个网络命名空间访问。默认情况下,Docker 容器有自己的网络命名空间,它附带另一个单独的 实例localhost

因此,使用默认的 Docker 网络,您想要的功能是不可能的:容器无法连接到主机的localhost

Docker还支持一种特殊的网络模式:主机网络。如果在启动容器时指定此项,则不会将其放入单独的网络命名空间,而是使用主机网络命名空间。主机和容器的网络命名空间localhost将相同。但是,有以下影响:

  • 端口映射无效
  • 您需要注意不要重复使用端口
  • 主机网络不能与链接混合

根据您的设置,nginx 失去对其他容器的访问权限是不可接受的。

您也可以使用类似的方法socat来让 Docker 容器可以访问该端口:

docker run -d --restart=always --network=host alpine/socat TCP4-LISTEN:4001,fork,reuseaddr,interface=docker0 TCP4-CONNECT:localhost:4001

从你的 nginx 容器,你可以使用默认网络访问 172.17.0.1 处的主机。

您还可以尝试添加--add-host=host.docker.internal:host-gateway到 nginx 容器调用中以获取 DNS 名称 ( host.docker.internal),无论配置如何,该名称始终有效。这仅适用于最新版本的 Docker。

相关内容