how to link docker container to each other with docker-compose
Updated for Docker 1.10
Docker 1.10 allows the definition of networks within the compose file. Here's the updated code
version: "2"
services:
replica1:
image: mongo:2.6.8
container_name: replica1
networks:
- my-net
ports:
- "27018"
environment:
REPLICA2_URL: "http://replica2:27019"
replica2:
image: mongo:2.6.8
container_name: replica2
networks:
- my-net
ports:
- "27019"
environment:
REPLICA1_URL: "http://replica1:27018"
networks:
my-net:
driver: bridge
Previous answer for Docker 1.9
As of Docker 1.9, the solution to this is to create a custom network and pass it to the docker-compose up
command.
Create a network
docker network create --driver bridge my-net
Reference that network as an environment variable (
${NETWORK}
)in the docker-compose.yml files. Eg:
```
replica1:
image: mongo:2.6.8
container_name: replica1
net: ${NETWORK}
ports:
- "27018"
environment:
REPLICA2_URL: "http://replica2:27019"
replica2:
image: mongo:2.6.8
container_name: replica2
net: ${NETWORK}
ports:
- "27019"
environment:
REPLICA1_URL: "http://replica1:27018"
```
Note that replica1
in http://replica1:27018
will resolve to the ip address of the replica1 service (container). No need to hardcode ip addresses; An entry for replica1 is automatically added to the /etc/host of the replica2 container. Same goes for the replica1 container. Docker will add an entry for replica2 in its /etc/host file.
- Call docker-compose, passing it the network you created
NETWORK=my-net docker-compose up -d -f docker-compose.yml
I've created a bridge network above which only works within one node (host). Good for dev. If you need to get two nodes to talk to each other, you need to create an overlay network. Same principle though. You pass the network name to the docker-compose up command.
Without updating the docker-compose.yml
file,
docker network connect docker-compose-network-you-want-to-connect conatianer-name-from-another-docker-compose
More here
You should use the ambassador pattern:
https://docs.docker.com/engine/admin/ambassador_pattern_linking/
Basically you create an intermediate component that bridges both of them together. You can see an example that we use with Spring Cloud's Eureka discovery service:
ambassador:
image: cpuguy83/docker-grand-ambassador
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
command: "-name eureka_1 -name eureka2_1 "
eureka:
links:
- "ambassador:eureka2"
eureka2:
links:
- "ambassador:eureka"
For simplicity, I only copied the links