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
Ok!!!
So it seems bridge doesn't resolve names
https://earthly.dev/blog/docker-networking/
more details are available here: https://docs.docker.com/network/network-tutorial-standalone/
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:
Then at the bottom of the yaml compose file (in all different compose files):
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:
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:
Adjust where needed, this is just Dockerfile an example of a React application.