【问题标题】:Docker nginx proxy works with docker-compose v1, but not v2?Docker nginx 代理适用于 docker-compose v1,但不适用于 v2?
【发布时间】:2017-05-03 20:53:13
【问题描述】:

我正在尝试为我的 docker 容器设置一个 nginx proxy 以使用简单的子域而不是端口。我喜欢使用 docker-compose 来启动我的容器,而且由于我对 docker 很陌生,所以我立即开始使用 v2 格式。

我花了很多时间弄清楚为什么这个非常流行且看似简单易用的 nginx 代理容器对我不起作用。原来这和我使用 docker-compose v2 有某种关系。

我将发布我首先使用的 docker-compose.yml 文件,但由于某种原因它不起作用:

version: '2'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    container_name: nginx-proxy
    network_mode: bridge
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    environment:
      - ENABLE_IPV6=true
      - DEFAULT_HOST=domain.com

  whoami:
    image: jwilder/whoami
    network_mode: bridge
    environment:
      - VIRTUAL_HOST=whoami.local

这是用于测试它的示例 Jenkins 容器:

version: "2"

services:
  jenkins:
    image: jenkins:2.46.2-alpine
    restart: always
    hostname: jenkins.domain.com
    network_mode: bridge
    expose:
      - 8080
      - 50000
    ports:
      - 8080:8080
      - 50000:50000
    volumes:
      - /srv/jenkins:/var/jenkins_home
    environment:
      - VIRTUAL_HOST=jenkins.domain.com
      - VIRTUAL_PORT=8080

现在我将发布实际确实为我工作的配置:

nginx-proxy:
  image: jwilder/nginx-proxy:alpine
  container_name: nginx-proxy
  ports:
    - 80:80
    - 443:443
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro
  environment:
    - ENABLE_IPV6=true
    - DEFAULT_HOST=domain.com

whoami:
  image: jwilder/whoami
  environment:
    - VIRTUAL_HOST=whoami.local

对于 Jenkins 容器:

jenkins:
  image: jenkins:2.46.2-alpine
  restart: always
  hostname: jenkins.domain.com
  expose:
    - 8080
    - 50000
  ports:
    - 8080:8080
    - 50000:50000
  volumes:
    - /srv/jenkins:/var/jenkins_home
  environment:
    - VIRTUAL_HOST=jenkins.domain.com
    - VIRTUAL_PORT=8080

我看到的唯一真正的区别是删除了network_mode: bridge。我补充说,当我注意到使用 v2 时会创建单独的网络,但使用 v1(或简单的 docker run)时,它们最终会在同一个网络上。使用network_mode: bridge 似乎可以解决这个问题。

除此之外,这只是docker-compose.yml 文件中的结构更改,但肯定还有其他一些差异会阻止此设置正常工作。

由于 V1 已被弃用,我想使用 v2 格式...我必须进行哪些更改才能使 docker-compose v2 像 v1 一样工作并让代理正常工作?

【问题讨论】:

  • 你看到了什么错误?
  • 其实没有错误。代理只是不工作,不会将请求转发到其他容器。

标签: docker docker-compose jwilder-nginx-proxy


【解决方案1】:

您需要确保容器位于同一网络上。在 nginx-proxy 中,如果无法到达节点,它不会添加上游设置。您应该会看到如下内容:

$ docker exec -it nginx-proxy cat /etc/nginx/conf.d/default.conf
# ....
# whoami.local
upstream whoami.local {
                                ## Can be connect with "nginxproxy_default" network
                        # nginxproxy_whoami_1
                        server 172.19.0.3:8000;
}
# ....

如果上游部分是空的,没有 cmets 和 server 行,那么它就无法找到一个通用的 docker 网络来访问容器,它也无法路由流量。

我在以下撰写文件中看到了这一点:

version: '2'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    container_name: nginx-proxy
    ports:
      - 8080:80
      - 8443:443
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    environment:
      - ENABLE_IPV6=true
      - DEFAULT_HOST=domain.com

  whoami:
    image: jwilder/whoami
    environment:
      - VIRTUAL_HOST=whoami.local

我可以通过以下方式验证它:

$ curl -H "Host: whoami.local" http://localhost:8080
I'm b066afdb6e45

使用 Jenkins,当您使用单独的 compose 文件(实际上是一个单独的 compose 项目,当您使用不同的目录名称时默认发生)时,它将获得一个单独的默认网络。我拥有的最简单的解决方案是使用外部网络。首先你直接在docker中创建:

$ docker network create proxynet

然后您的撰写文件将包含该外部网络:

version: '2'

networks:
  proxynet:
    external: true

services:
  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    container_name: nginx-proxy
    ports:
      - 8080:80
      - 8443:443
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
      - proxynet
    environment:
      - ENABLE_IPV6=true
      - DEFAULT_HOST=domain.com

  whoami:
    image: jwilder/whoami
    environment:
      - VIRTUAL_HOST=whoami.local
    networks:
      - proxynet

你会对 Jenkins 做同样的事情:

version: "2"

networks:
  proxynet:
    external: true

services:
  jenkins:
    image: jenkins:2.46.2-alpine
    restart: always
    hostname: jenkins.domain.com
    networks:
      - proxynet
    expose:
      - 8080
      - 50000
    ports:
      - 8080:8080
      - 50000:50000
    volumes:
      - /srv/jenkins:/var/jenkins_home
    environment:
      - VIRTUAL_HOST=jenkins.domain.com
      - VIRTUAL_PORT=8080

【讨论】:

  • 感谢您的回答。我稍后会对其进行测试并验证它是否有效。但我不明白的是:为两个容器设置共享外部网络或在两者中使用network_mode: bridge 将它们放在同一个默认桥接网络上的区别在哪里?
  • 我需要对其进行测试,但桥接是默认的网络模式,因此它可能会继续执行默认操作,即为每个项目创建一个唯一的网络(v2 功能)。
  • 列出网络不会列出任何其他网络(除了 3 个默认网络)。但是,如果没有network_mode: bridge,还有 2 个额外的网络(一个用于 nginx,一个用于 jenkins)。
  • 确实如此。我不能让network_mode: bridge 破坏我的环境,只要一切都在那里,nginx_proxy 会看到每个容器并中继流量。
  • 嗯,这很奇怪。我认为 docker 容器在每个 docker 平台上的工作方式都是一样的……无论如何,明确使用共享的外部网络是可行的,所以我要这样做。
猜你喜欢
  • 1970-01-01
  • 2017-03-25
  • 2018-03-09
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 1970-01-01
相关资源
最近更新 更多