如何连接到 docker-compose 中的命名网络

How to connect to named networks in docker-compose

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

不配置网络,当我在同一个容器中时,我可以连接我的不同服务器,但我无法从前端组合容器访问 mongodb 数据库 url: mongodb://weallyback_default:27017/weally

这是我的前端撰写配置

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 网络检查 时网络似乎正常,但我看到了前端实例 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 urls:

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:

这在 p运行ing

之后给出了这些网络
> 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,我的url应该是正确的,我不知道缺少什么

好的!!!

所以网桥似乎无法解析名称

The downside with the bridge driver is that it’s not recommended for production; the containers communicate via IP address instead of automatic service discovery to resolve an IP address to the container name.

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

此处提供更多详细信息:https://docs.docker.com/network/network-tutorial-standalone/

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

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

services:
  serviceName:
    networks:
      - myNetwork

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

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 应用的例子。