Docker Compose: Link containers outside compose file using external_links

Linking containers is one of Docker’s basic concept: It allows for accessing network services a certain container offers without the need of exposing the needed port(s) to the Docker host. The same concept is available in Docker Compose. However, it get’s a bit more complicated when it comes to linking a container not defined in the same compose file (docker-compose.yml).

Linking containers without Docker Compose is easy using the –link parameter:

docker run --name test1 something
docker run --name test2 --link test1:test1 something

Here, a container named test1 is started first, afterwards, a second container test2 is started. Container test1 gets linked to test2, so you can access test2 from within test1 just by using test1’s name (test1).

The same thing is possible if you have two services defined within one Docker Compose File:

version: '2'
services:
  test2:
    image: something
    depends_on:
      - test1
    links:
      - test1
  test1:
    image: something

The result is exactly the same as with the docker run command.

But how can you link containers not defined in the same docker compose file?

I have such a scenario: I have multiple docker compose files, one for each domain, each defining tightly related services (such as blog, backend services and database). Then I have one frontend web server accessible from the internet, proxying incoming requests to the various services defined in multiple docker compose files.

Docker Compose offers the “external_links” configuration option which allows you to link containers not defined in the compose file:

version: '2'
services:
  test2:
    image: something
    external_links:
      - domainA_test1_1

Here, “test1” is a service defined in the composition “domainA”. Docker Compose automatically adds a “_1” to the container name (as long as it’s the first and only running instance).

However, things get a bit more complex here. The reason for this is that Docker by default automatically creates a separate network for each docker composition. Every container defined in the same docker compose file gets attached to the same network. The networks can’t access each other if you don’t do something about it.

 

Option 1: Make your container requiring the link a member of the foreign networks

To do this, you need to add two sections to the docker compose file where you want to define the link: Make the specific container a member of the foreign network and define for the docker compose file itself that these networks are external.

version: '2'
services:
  test2:
    image: something
    external_links:
      - domainA_test1_1
    networks:
      - default
      - domainA_default
networks:
  domainA_default
    external: true

As you can see, “domainA_default” is the network that docker automatically has created for the composition “domainA”. Additionally, I’ve attached the service to the default network.

In test2, you can access test1 using it’s default DNS name “domainA_test1_1”.

You can view a list of all docker networks using this command:

docker network ls

 

Option 2: Set bridge networking mode for all containers you want to link with each other

Option 1 allows for private networks linked with each other. However, you may run into issues if you need to initiate outbound connections from within your linked containers.

Therefore, another option is to enable the bridged networking mode for all the containers you want to link together:

version: '2'
services:
  test2:
    image: something
    network_mode: bridge
    external_links:
      - domainA_test1_1
version: '2'
services:
  test1:
    image: something
    network_mode: bridge

Which option is right for you, depends on your concrete situation. I personally prefer option 1, because it uses private networks instead of bridging the containers to the host network.

10 thoughts on “Docker Compose: Link containers outside compose file using external_links”

  1. If anyone is trying to mix linking across compose files, while still having other depends_on containers within each compose service, option 1 is your life saver!

  2. New to docker-compose. Cant get external_link to work. Using option two. Both containers is running bridge (according to network ls).

    I thought I should use the linked container name (according to docker-composer doc) but here you are using domainA__1?

    What is the domainA stuff?

  3. Got it working. Missed the network_mode in one.

    The linked container name is now added in /etc/host pointing to right IP

  4. I tried to use option one with your step. but didn’t work.
    could you please write all whole docker-compose files as an example?
    Option two is working. Thanks for your writing.

Leave a Reply

Your email address will not be published. Required fields are marked *