【问题标题】:How to connect to named networks in docker-compose如何在 docker-compose 中连接到命名网络
【发布时间】:2021-07-30 10:18:29
【问题描述】:

我有一个依赖于 4 个后端服务器(redis、mongo、graphql-websockets-subscriptions 和 graphql-http)和一个前端的应用程序

没有配置网络,当我在同一个容器中时,我可以连接不同的服务器,但我无法从前端 compose-container 访问 mongodb 数据库,其 url 为:mongodb://weallyback_default:27017 /很好

这是我的前端撰写配置

version: "3.8"

services:
  next_server:
    image: node:14.17.3-alpine
    volumes:
      - type: bind
        source: ./
        target: /front
      - type: volume
        source: nodemodules # name of the volume, see below
        target: /front/node_modules
        volume:
          nocopy: true
    working_dir: /front
    command: yarn dev
    ports:
      - "3000:3000"
    networks:
      - weallyback_default
    environment:
      - NODE_ENV=development
      - PORT=3000

volumes:
  nodemodules:

networks:
  weallyback_default:
    external: true

知道我的后端配置暴露了默认网络weallyback_default

D:\Zied\work\WeAllyBack>docker network ls
NETWORK ID     NAME                 DRIVER    SCOPE
71d1c5f23159   bridge               bridge    local
cd980f642e7b   host                 host      local
4a50359ad823   none                 null      local
ecec643b2a2e   weallyback_default   bridge    local

这导致我尝试配置网络,但这破坏了同一容器中实例之间的连接:

据我了解,如果我想在不同的 docker-compose 文件中使用它们,我必须将它们声明为外部网络。所以我开始为我的网络命名,但无论如何我都无法让它工作:

所以我将这些网络声明附加到前端 (weallyorg_next_server_1) 服务器的配置中

networks:
  graphql_server:
    external: true
  graphql_pubsub_server:
    external: true
  mongo_server:
    external: true

这是我的 4 个后端服务器的配置:

version: "3.8"

services:
  redis-server:
    container_name: redis-server
    image: 'redis:6.2-alpine'
    ports:
      - "6379:6379"
    networks:
      - redis_server
  mongo-server:
    container_name: mongo-server
    image: mongo:4.4.5
    ports:
      - "27001:27001"
    volumes:
      - mongodb:/data/db
      - mongodb_config:/data/configdb
    networks:
      - mongo_server
    restart: always
  graphql_server:
    container_name: graphql_server
    depends_on:
      - mongo-server
      - redis-server
    image: node:14.17.3-alpine
    volumes:
      - type: bind
        source: ./
        target: /app
      - type: volume
        source: nodemodules # name of the volume, see below
        target: /app/node_modules
        volume:
          nocopy: true
    working_dir: /app
    command: yarn dev
    ports:
      - "4000:4000"
    networks:
      - graphql_server
      - mongo_server
    environment:
      - NODE_ENV=development
      - PORT=4000
  graphql_pubsub_server:
    container_name: graphql_pubsub_server
    depends_on:
      - mongo-server
      - redis-server
    image: node:14.17.3-alpine
    volumes:
      - type: bind
        source: ./
        target: /app
      - type: volume
        source: nodemodules # name of the volume, see below
        target: /app/node_modules
        volume:
          nocopy: true
    working_dir: /app
    command: yarn dev-sub
    ports:
      - "4001:4001"
    networks:
      - graphql_pubsub_server
      - mongo_server
      - redis_server
    environment:
      - NODE_ENV=development
      - PORT=4000

volumes:
  nodemodules:
  mongodb:
  mongodb_config:

networks:
  graphql_server:
    name: graphql_server
    driver: bridge
  graphql_pubsub_server:
    name: graphql_pubsub_server
    driver: bridge
  mongo_server:
    name: mongo_server
    driver: bridge
  redis_server:
    name: redis_server
    driver: bridge

当我尝试将 graphql 服务器连接到 mongo 和 redis 时,它不起作用:

const DEV_URL_LOCAL = 'mongodb://mongo-server:27017/weally';

export const pubsub = new RedisPubSub({connection:{
        host: 'redis-server',
        port: 6379
    }});

尽管当我运行 docker network inspect 时网络似乎没问题,但我在容器列表中看到了关联的前端实例 weallyorg_next_server_1

D:\Work\WeAllyBack>docker network ls
NETWORK ID     NAME                    DRIVER    SCOPE
2dbd93a99f96   bridge                  bridge    local
58c1d94a2f2e   graphql_pubsub_server   bridge    local
62d20fee3c3a   graphql_server          bridge    local
b16be840cbd1   host                    host      local
655197efa0d7   mongo_server            bridge    local
c2c845f1c14c   none                    null      local
0b95acfd581d   redis_server            bridge    local
ee7d85a80a09   weallyback              bridge    local

D:\Work\WeAllyBack>docker network inspect mongo_server
[
    {
        "Name": "mongo_server",
        "Id": "655197efa0d7c0070ea3a5e2fba565c117bde72efaf4e5952fe6e2c1499199a0",
        "Created": "2021-08-02T12:05:15.397633Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "438cdfa8fc24ef3c2a537c3746f2a82e29bdb29e6c925e34587531819f96cfa3": {
                "Name": "graphql_pubsub_server",
                "EndpointID": "05ce92ae14016d6144c97748e5a1718a62ab4fc14d6518d2b33bd2f2077fb229",
                "MacAddress": "02:42:ac:14:00:05",
                "IPv4Address": "172.20.0.5/16",
                "IPv6Address": ""
            },
            "b71e428de30e01b13c1cc83ecc083baac88fdb7f01a0385a0984000e24dc2f52": {
                "Name": "mongo-server",
                "EndpointID": "cac16e9c451f24a708d5b678b69beb54358f49960700e240975c4634bb90b9ac",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            },
            "ee8ef82c6751946d68a7ec295d266306ef992bc30f3314eeb432080db42db877": {
                "Name": "graphql_server",
                "EndpointID": "5a198664afc78c8f8b23682288f4ea42f0253e448b4968c0af3e2f878d8835a8",
                "MacAddress": "02:42:ac:14:00:04",
                "IPv4Address": "172.20.0.4/16",
                "IPv6Address": ""
            },
            "f2405fe94eb5c7638b8cad062665a35b224b86b887822ed384c9a840d1eab622": {
                "Name": "weallyorg_next_server_1",
                "EndpointID": "df8930f6e5bc141cf2992fd81c552ee58944e9c5036a64f0a09ca9206e2808c0",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "mongo_server",
            "com.docker.compose.project": "weallyback",
            "com.docker.compose.version": "1.29.2"
        }
    }
]

我是 Docker 新手,所以我真的很困惑下一步该做什么......

请注意,如果我删除网络特定设置一切正常,我只想将我的前端服务器配置放在不同的 docker-compose 文件中,所以我想命名网络以从另一个访问它们(前面结束)容器。 此配置适用于 redis-server:6379 和 mongodb://mongo-server:27017/weally url:

version: "3.8"

services:
  redis-server:
    image: 'redis:6.2-alpine'
    ports:
    - "6379:6379"
  mongo-server:
    image: mongo:4.4.5
    ports:
    - "27001:27001"
    volumes:
    - mongodb:/data/db
    - mongodb_config:/data/configdb
    restart: always
  graphql_server:
    depends_on:
      - mongo-server
      - redis-server
    image: node:14.17.3-alpine
    volumes:
      - type: bind
        source: ./
        target: /app
      - type: volume
        source: nodemodules # name of the volume, see below
        target: /app/node_modules
        volume:
          nocopy: true
    working_dir: /app
    command: yarn dev
    ports:
      - "4000:4000"
    environment:
      - NODE_ENV=development
      - PORT=4000
  graphql_pubsub_server:
    depends_on:
      - mongo-server
      - redis-server
    image: node:14.17.3-alpine
    volumes:
      - type: bind
        source: ./
        target: /app
      - type: volume
        source: nodemodules # name of the volume, see below
        target: /app/node_modules
        volume:
          nocopy: true
    working_dir: /app
    command: yarn dev-sub
    ports:
      - "4001:4001"
    environment:
      - NODE_ENV=development
      - PORT=4000

volumes:
  nodemodules:
  mongodb:
  mongodb_config:

这会在修剪后给出这些网络

> docker network ls
NETWORK ID     NAME                 DRIVER    SCOPE
71d1c5f23159   bridge               bridge    local
cd980f642e7b   host                 host      local
4a50359ad823   none                 null      local
e4cf4a71d49a   weallyback_default   bridge    local

我怀疑我的连接 url 的格式有误,但我找不到设置正确的信息。 我红了一些教程like this one,我的网址应该是正确的,我不知道缺少什么

【问题讨论】:

  • p.s:我在这里的 docker 社区论坛上问过:forums.docker.com/t/…
  • 除非您需要将不同的资源放在不同的网络中,否则您可以将它们全部添加到同一个网络中。这样您就可以使用主机名访问它们,而无需将它们暴露给主机网络。
  • 这就是我第一次尝试做的事情,使用默认网络“weallyback_default”并仅公开前端端口号。但它不起作用,所以我开始命名我的个人网络。但正如我在回答中提到的,似乎桥不解析名称,它只“理解”IP 地址(在每次启动时动态创建不同)
  • 我没有看到你如何连接到 mongodb://mongo-server:27017/weally 并且你的 docker compose 绑定了 27001:27001 :D

标签: docker-compose docker-networking


【解决方案1】:

您可以为您的应用程序设置一个网络,在所有容器中重复使用相同的网络。这样您就可以按名称解析所有应用程序。

在服务下为每个服务添加以下内容:

services:
  serviceName:
    networks:
      - myNetwork

然后在 yaml compose 文件的底部(在所有不同的 compose 文件中):

networks:
  myNetwork:
    external:
      name: myNetwork

然后就可以根据容器名称解析所有应用了。

编辑

当使用前端并且您还想从浏览器向不同的容器发出请求时,您需要设置某种反向代理。使用例如Nginx 将请求从前端传递到指定的 docker 容器。使用类似的配置:

server {
    listen 80;
    listen [::]:80;

    location /api/graphql {
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_pass              http://graphql_server:6379;
    }
    location /api/graphql-pubsub {
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_pass              http://graphql_pubsub_server:27001;
    }

# Add configuration for other services if you need to access them from the front end

    error_page 404 /404.html;
    location = /404.html {
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    } 
}

然后在本例中,将通过使用前端应用程序的基本 URL 调用 /api/graphql 从浏览器实现对 graphql 服务器的请求。

这需要你使用 nginx 基础容器,这可以通过一个 docker 文件来完成,例如:

FROM node:15.8.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY yarn.lock ./
RUN yarn install
RUN yarn add react-scripts@4.0.2 -g --silent
COPY . ./
RUN yarn build

FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY --from=build /app/nginx.proxy.conf /etc/nginx/conf.d/nginx.proxy.conf
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]

根据需要调整,这只是 Dockerfile 一个 React 应用的示例。

【讨论】:

  • 这与在前端使用后端配置的默认名称基本相同:'weallyback_default',不幸的是,这对我不起作用
  • 是的,我忘了提到这对于前端来说是不够的。浏览器将无法解析 docker 容器名称,因此您需要添加反向代理。查看编辑。
  • 实际上我可以在没有这些额外设置的情况下连接到 localhost:3000,在生产中我只需要打开端口 80 并通过 ngnix 将其重定向到 3000。我的问题不存在。我通过将前端服务器撰写配置放在同一个文件中解决了这个问题。我将在我的答案中发布,因为命名网络不适用于桥接(并且主机不在 docker 桌面下)
  • 只要所有容器都在同一个网络中,解析容器名称应该可以使用桥接网络。当您将所有服务放在同一个 compose 文件中而不指定网络时,docker compose 将为所有容器创建一个默认的桥接网络并将它们链接在一起,这就是您可以使用这种方式通过名称解析的原因。但这也可以使用多个撰写文件来完成。通过使用相同的桥接网络,或链接桥接网络。见documentation
  • 是的,我看到了文档,这就是我创建这个问题的原因,因为它对我不起作用。您可以在问题中看到 docker 检测到前端容器 weallyorg_next_server_1(不在同一个 compose 容器中)(请参阅命令:docker network inspect mongo_server)。但是我的连接拒绝工作。所以事情没有像文档中描述的那样表现,这就是我发布这个问题的原因,我在回答中分享的帖子确认/解释了发生在我身上的事情。
【解决方案2】:

好的!!!

所以桥似乎无法解析名称

桥接驱动程序的缺点是不推荐用于 生产;容器通过 IP 地址而不是 自动服务发现以将 IP 地址解析到容器 名字。

https://earthly.dev/blog/docker-networking/

更多详情请点击此处:https://docs.docker.com/network/network-tutorial-standalone/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2023-03-20
    相关资源
    最近更新 更多