107
votes

I am setting up my local development environment with docker containers. The docker-compose.yml is like following

version: '2'

services:
  db:
    image: mongo:3
  mq:
    image: rabbitmq:3
  api:
    build: .
    image: my_app/api
    ports:
      - "3000:3000"
    links:
      - db
      - mq
    environment:
      - NODE_ENV=development

It starts without error. And docker lists 3 running containers

docker-compose up -d
docker ps

e90e5a8b5d33        my_app/api    "/usr/local/bin/node "   0.0.0.0:3000->3000/tcp               my_app_api_1
42bfcd971b16        mongo:3       "/entrypoint.sh mongo"   27017/tcp                            my_app_db_1
a0685a816c47        rabbitmq:3    "/docker-entrypoint.s"   4369/tcp, 5671-5672/tcp, 25672/tcp   my_app_mq_1

However when I try to link to those running containers from another container

docker run --link my_app_mq_1:mq --link my_app_db_1:db -it worker 

I get error

 docker: Error response from daemon: Cannot link to /my_app_mq_1, as it does not belong to the default network.

I have also tried

 docker run --link my_app_mq_1:mq --link my_app_db_1:db -it --net default worker 

Same error.

So how can I link to a running container started by docker-compose?

3

3 Answers

210
votes

Ok, found the answer to it. In case anyone else comes across the same problem, just do

docker network ls

This command lists all the docker networks. docker-compose will create a new network when you run docker-compose up. In my case, the network is named as myapp_default.

Note: Your app’s network is given a name based on the “project name”, which is based on the name of the directory it lives in. You can override the project name with either the --project-name flag or the COMPOSE_PROJECT_NAME environment variable. Networking in Compose

So the correct way to link to those containers is

docker run --link my_app_mq_1:mq --link my_app_db_1:db -it --net myapp_default worker 
13
votes

my command to run links

docker run --network=YOUR_NETWORK --link SERVICE -t -i app command
2
votes

When you use service definition version 2 and more, docker-compose creates user-defined network. Name resolution in a user-defined network works via Docker embedded DNS server. Here's related quote from documentation:

The Docker embedded DNS server enables name resolution for containers connected to a given [user-defined] network. This means that any connected container can ping another container on the same network by its container name.

Containers are also available by network aliases that docker-compose creates. It can be verified by command like:

docker inspect \
  -f '{{json .NetworkSettings.Networks.myapp_default.Aliases}}' my_app_db_1

It prints ["db","$CONTAINER_ID"].

Providing links with --link will not have any effect in case of existing user-defined network. You can make sure and look at /etc/hosts, which will not have the corresponding lines.

Thus the following command is sufficient:

docker run -it --net myapp_default worker