在同一主机上运行多个nginx docker容器是否可行?

19

仅使用docker-compose,是否可以在同一主机上挂载多个nginx容器,并使每个容器共享端口80?

我想整理一个在同一主机上运行多个应用程序的系统。 每个应用程序由几个链接的docker容器组成,通过docker-compose文件彼此绑定,每个应用程序都使用主机系统的nginx作为反向代理暴露给世界。目前来看还不错。

每次我添加新的docker应用程序,我都需要为该应用程序在主机nginx中添加一个新的nginx.conf文件,但我更喜欢将nginx配置与应用程序的docker-compose文件捆绑在一起作为nginx容器,从而使每个应用程序在容器中干净地维护其所需的所有内容。然而,每个nginx容器需要侦听端口80,因此只有第一个可以绑定。主机nginx可以侦听端口80上的几个Web应用程序,但是否可以多个nginx实例做相同的事情?

更新:

因此,似乎这并不是严格可行的。目标是尽可能将特定于应用程序的大量nginx配置捆绑到应用程序中,因此我正在尝试一种解决方案,其中应用程序仍会启动自己的nginx容器,而主机nginx仅处理指向应用程序nginx的url路由。不确定性能如何,但这大大减少了应用程序与主机之间的纠缠。


我认为这是不可能的。Nginx似乎在您的容器之间进行负载平衡,因此它存在于容器的上一层,并且无法由它们管理。 - ssc327
您可以使用不同的端口运行尽可能多的容器。但是,为什么需要运行多个nginx容器呢?只需运行一个容器,并使用多个服务器块进行proxy_pass,以满足所需的应用程序数量即可。我认为只需要使用include属性的服务器块,而不是运行多个容器。 - Jinna Balu
2
@JinnaBalu 的意思是将所有配置整齐地放在每个项目的一个 docker-compose.yml 文件中。我怀疑这是不可能的,但我想问一下以免遗漏。 - Shukri Adams
2个回答

27

虽然已经过了几年,但我觉得回答这个问题对于其他遇到这个问题的人可能有所帮助。

不幸的是,不可能在同一个端口上拥有多个容器。这是由于操作系统的本质所决定的。但我认为我可以理解你的意图。你想要拥有多个自定义配置的 Web 应用程序。

实现这一目标的最佳方法是通过反向代理。反向代理允许您将请求从主端口(如 80 和 433)转发到其他端口或地址上的 Web 服务器。假设所有的容器都有 Nginx (或任何其他 Web 服务器)的实例,并且都有您的配置和代码。有两种方法可以实现这一点。

在 Docker 中,最简单的方法是使用 nginx-proxy 项目。只需在 docker-compose 中添加一个环境变量,管理的 nginx 容器就会自动将您的请求转发到设置的站点。这似乎是您想要做的,因为它只需要一个 docker-compose。

您也可以自己管理。使所有站点在 nginx 上监听其他端口,并有一个主 nginx 容器监听端口 80 和 433,并使用您创建的反向代理将请求转发到另一个端口。

祝你好运!


-1

这是一篇很老的帖子,但对于那些通过搜索到达此处的人来说,你们可能可以在2023年使用这个组合配置来实现这个目标:


    version: "3"
    services:
      nginx:
        image: nginx:latest
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
        ports:
          - "80"

注意:


    ports:
     - "80"

这不是一个错误。与典型的端口映射,例如仅指定单个端口的80:80不同,Docker Compose 应该使用虚拟端口分片来动态映射请求,使用轮询算法将请求均匀地分配给运行的服务的每个实例。因此,如果要运行三个实例,则理论上可以执行以下操作:

docker-compose up --scale nginx=3

这将运行3个nginx实例。如果在Compose文件中定义了另一个服务,例如expressjs,您也可以利用相同的策略,使用简单的nginx配置来使用Docker的嵌入式动态DNS。


    # nginx.conf
    user  nginx;
    
    events {
        worker_connections   1000;
    }
    http {
            server {
                  listen 80;
                  location / {
                    proxy_pass http://expressjs:3000;
                  }
            }
    }

然后像这样定义您的组合:


    version: "3"
    
    services:
      expressjs:
        image: expressjs:latest
        ports:
          - "3000"
        depends_on:
          - nginx
      nginx:
        image: nginx:latest
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
        ports:
          - "80"

我还没有测试过,但是理论上应该可以工作。

参考:https://docs.docker.com/config/containers/container-networking/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接