在一个子域上托管多个 Docker 网络服务

时间:2021-02-03 11:45:57

标签: docker web-services nginx webserver reverse-proxy

我已经在网上搜索了好几个小时,但还没有找到满意的答案。我会尽量清楚地解释我的需求。

我有一个运行带有多个容器的 docker 环境(Photon OS)的虚拟机。目的是建立一种内联网。我希望将所有内容(至少是有意义的内容)放在一个子域中,因为这样“客户”更容易理解和导航。

我知道如何使用 nginx 使容器在多个子域下可用。我目前正在为此使用带有 nginx-proxy-manager 的容器。到目前为止效果很好,但是对于每项服务,我都必须注册另一个 CNAME。这意味着我无法真正将某些服务整合在一起。我举个例子:

假设我有一个像 Nextcloud 这样的容器,它依赖于一个数据库容器 (postgresql)。为了访问数据库,我需要 Adminer 作为第三个容器。 在我目前的情况下,我必须为 Nextcloud 和数据库前端注册至少两个 CNAME:

  • nextcloud.example.com
  • dbadmin.example.com

让我们进一步假设我想要一个额外的 DokuWiki 容器(我知道我可以将它托管在一个普通的网络服务器上),它需要另一个 db 和另一个 db-frontend。我将不得不再注册两个 CNAME:

  • wiki.example.com

  • dbadmin.example.com ...等等。怎么办? dbadmin-2.example.comwiki-db.example.com

现在我决定为我的用户添加一个 Bitwarden 实例并且必须注册

  • pass.example.com

我想访问整个结构而不是所有这些子域/CNAME,如下所示:

  • intranet.example.com/cloud/main 服务 Nextcloud
  • intranet.example.com/cloud/dbadmin 为 Nextcloud 的 Adminer 实例提供服务
  • intranet.example.com/wiki/main 服务于 DokuWiki
  • intranet.example.com/wiki/dbadmin 为 DokuWiki 的 Adminer 实例提供服务
  • intranet.example.com/passwords 为 Bitwarden 实例提供服务

我不打算覆盖成千上万的用户。总共可能不超过50个,更不用说同时进行了。所以负载平衡的优势并不是我真正需要的。

那么现在我的主要问题是:我如何f实现这一目标?

我尝试将 nginx 配置为在不同位置提供不同的服务。我遵循的任何教程基本上都是这样做的:

location /cloud/main {
    proxy_pass http://172.18.0.1:<nextcloud-port>;
}

location /cloud/dbadmin {
    proxy_pass http://172.18.0.1:<adminer-nxt-port>;
}

location /wiki/main {
    proxy_pass http://172.18.0.1:<dokuwiki-port>;
}

location /wiki/dbadmin {
    proxy_pass http://172.18.0.1:<adminer-wiki-port>;
}

location /passwords {
    proxy_pass http://172.18.0.1:<bitwarden-port>;
}

这甚至可以有点。如果我访问 intranet.example.com URL 之一,请求将转发到正确的容器。但响应并未根据服务所在的位置进行调整。

如果我访问 intranet.example.com/cloud/main,Nextcloud 实例会在其根目录上获取请求并尝试将我重定向到 <root>/#/login。这显然只在 nextcloud 在域的根上运行时才有效,但事实并非如此。 我希望 nginx(或任何其他合适的反向代理)来执行此操作:

  • 用户请求intranet.example.com/cloud/main/
  • 代理在 intranet.example.com 上侦听端口 80 并接收请求 /cloud/main/
  • 代理知道 /cloud/main 上的流量转到 Nextcloud 并将请求 / 定向到 http://172.18.0.1:<nextcloud-port>
  • 容器发送重定向响应 /#/login/
  • 代理重新添加响应路径:/cloud/main/#/login/
  • 用户收到响应:重定向到 /cloud/main/#/login/
  • 用户遵循重定向并请求 intranet.example.com/cloud/main/#/login/
  • 代理在 intranet.example.com 上侦听端口 80 并接收请求 /cloud/main/#/login/
  • 代理知道 /cloud/main 上的流量转到 Nextcloud 并将请求 /#/login/ 定向到 http://172.18.0.1:<nextcloud-port>
  • 容器找到并返回登录页面。
  • 代理将容器的位置 /cloud/main 添加到 URL 和 html 的内容中,以便所有链接都指向正确的位置。
  • 用户在 URL intranet.example.com/cloud/main/#/login/ 上收到登录页面,状态完全正常。

有没有可能让 nginx、traefik 或其他任何东西做到这一点?也许这只是我缺少的简单重写行?也许这是 nginx-proxy-manager 的问题,这应该正常工作?感谢任何帮助,但请不要不要建议做一些完全不同的事情,除非它实现了相同的用户体验。

0 个答案:

没有答案