skip to Main Content

I have an app that relies on 4 backend servers (redis, mongo, graphql-websockets-subscriptions, and graphql-http) and one front end

Not configuring networks, I am able to connect my different servers while I’m in the same container, but I cannot access the mongodb database from the front-end compose-container with the url: mongodb://weallyback_default:27017/weally

This is my front-end compose config

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

Knowing that my backend config exposes the default network weallyback_default

D:ZiedworkWeAllyBack>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

That led me to attempt to configure networks, but that broke even connections between instances in the same container:

From what I understood, I have to declare networks as external if I want to use them in a different docker-compose file. So I started naming my networks, but I can’t get it to work anyways:

So I appended these networks declarations to the front-end (weallyorg_next_server_1) server’s config

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

This is the config for my 4 backend servers:

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

When I try to connect the graphql servers to mongo and redis, it doesn’t work:

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

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

Even though the networks seem to be ok when I run docker network inspect, I see the front-end instance weallyorg_next_server_1 associated in the containers list:

D:WorkWeAllyBack>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:WorkWeAllyBack>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"
        }
    }
]

I’m new to Docker, so I’m really confused about whet to do next…

Please note that if I remove the network specific settings everything works fine, I just want to have my front end server configuration in a different docker-compose file, so I want to name the networks to access them from the other (front end) container.
This config works for redis-server:6379 and 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:

This gives theses networks after pruning

> 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

I suspect the format of my connection url to be wrong but I can’t find the info to set it right.
I’ve red some tutorials like this one, and my urls should be correct, I can’t figure out what is missing

2

Answers


  1. Chosen as BEST ANSWER

    Ok!!!

    So it seems bridge doesn't resolve names

    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/

    more details are available here: https://docs.docker.com/network/network-tutorial-standalone/


  2. You can setup a single network for your application reusing the same network in all containers. This way you can resolve all applications by name.

    Under the services add the following for each service:

    services:
      serviceName:
        networks:
          - myNetwork
    

    Then at the bottom of the yaml compose file (in all different compose files):

    networks:
      myNetwork:
        external:
          name: myNetwork
    

    Then you can resolve all applications based on container name.

    Edit

    When using a front-end and you also want to make requests from the browser to the different containers you need to setup some sort of reverse proxy. Using e.g. Nginx to pass requests from the front end to the specified docker container. Using a configuration similar to:

    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 {
        } 
    }
    

    Then in this example a request to the graphql server would be achieved from the browser by calling /api/graphql using the base url of your front end application.

    This would require you to use the nginx base container, this can be done with a docker file like:

    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 [email protected] -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;"]
    

    Adjust where needed, this is just Dockerfile an example of a React application.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search