在不同的端口上运行单独的 Docker 应用程序,其中一个作为子域

在不同的端口上运行单独的 Docker 应用程序,其中一个作为子域

我已经将我的个人网站重建为 Dockerized 链以及同事的 Web 应用程序。这两个项目都是使用容器构建的,显示在两个单独的端口上,一个在端口 80 上,一个在端口 2019 上。每个都运行单独的 Certbot 容器以保持 SSL 加密。我还没有将 Nginx 作为主机的一部分运行,我只是将主机上的端口映射到运行每个应用程序的 Nginx 容器。

我想要的是,example.com作为我的个人网站,显示端口 80 上显示的内容,并作为application.example.comWeb 应用程序的代理。就上下文而言,每个 Docker 链都是一个 Django 项目,分别使用独立的 PostgreSQL、Certbot 和 Nginx 链来处理数据库、SSL 和托管。

我需要在主机上设置 Nginx 来处理路由吗?如果是这样,我该怎么做才能保持每个应用程序的 SSL 保护?

答案1

我是否需要在主机上设置 Nginx 来处理路由?

听起来您希望所有域都使用相同的标准 HTTP(S) 端口。在这种情况下,是的,您需要一个充当“反向代理”的中央 Nginx(或 Apache 或 HAproxy)实例。(最简单的方法是将其放在主机上,但它可以是自己的容器。)

  • “中央” nginx 监听端口 80(用于 HTTP)和 443(用于 HTTPS)
  • 用户访问时https://foo.example.com无需指定自定义端口,直接连接到“中央”nginx 实例
  • Nginx 根据proxy_pass配置连接到适当的 Docker 容器的地址:端口:

    server {
        server_name foo.example.com;
        listen ...;
        ssl_certificate ...;
        location / { proxy_pass http://<docker_ip>:2019; }
    }
    
    server {
        server_name bar.example.com;
        listen ...;
        ssl_certificate ...;
        location / { proxy_pass ...; }
    }
    

另一方面,如果您特别希望自定义端口出现在 URL 中(例如https://sub.example.com:2019),则不需要 HTTP 代理 - 只需通过 iptables 进行 TCP 级别的“端口转发”,不同的域名根本不会影响任何内容。

我该如何做到这一点并保留每个应用程序的 SSL 保护?

在这种情况下,TLS 是逐跳的,即客户端→反向代理和反向代理→Web 服务器是两个单独的 TLS 连接。第一个需要 Certbot,因为它通过互联网传输。(然而,第二个是系统内部的,不需要太多 TLS。)

换句话说,您必须将 Certbot 证书移至“中央” nginx 实例。您可以通过两种方式进行配置:

  1. Nginx 将所有请求代理到 Docker 容器。容器运行自己的 Certbot 实例,每次更新后,它们都会以某种方式将新证书和密钥复制到主机系统,以便“中央”Nginx 可以使用它。

  2. Nginx 代理所有请求除了 /.well-known/acme-challenge/。只有“中央” Nginx 系统运行 Certbot 并处理所有域的续订。容器不运行 Certbot;它们要么根本不使用 TLS,要么使用自颁发的证书。


尽管如此,还是可以实现端到端 TLS,其中主机路由连接完全基于 TLS“服务器名称指示”字段。可以使用 HAproxy 和 sniproxy 代替 Nginx 来实现这一点。

相关内容