kramer65
kramer65

Reputation: 53943

Why do I need a default docker network to start a common docker network for two docker-compose projects?

I've got two projects (a and b) which both have a docker-compose.yml file. I now want one of the projects to be able to call a service of the other project and as far as I know I need to create a common docker network for that. So to create a minimal example I made two folders (a/ and b/) which both contain a docker-compose.yml file.

This is the one in folder a/:

version: '3'

services:
  common_server:
    image: ubuntu
    ports:
      - 4444:4444
    command: >
      bash -c '
      apt update && apt install netcat -y && 
      while true; do echo -e "HTTP/1.1 200 OK\n\npong" | nc -k -l -p 4444 -q 1; done'
#    networks:
#      - my_network

  project_a:
    image: ubuntu
    depends_on: 
      - common_server
#    networks:
#      - my_network
    command: >
      bash -c '
      apt update && apt install curl -y && 
      while true; do echo "Calling the container";  echo "AAAAAAAA"; curl common_server:4444; sleep 10; done'

#networks:
#  my_network:
#    driver: bridge

This sets up two things:

This works great like this. I quickly checked the docker networks using:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5ac503033848        a_default           bridge              local  <== THIS NETWORK WAS CREATED
1f65f9c91441        bridge              bridge              local
72fcb38f2060        host                host                local
b76cd7ef1ac9        none                null                local

I've got a second docker-compose.yml file in the folder b/ from which I also want to call the common_server defined in the file above. So I uncommented the lines with the network in the file above to enable my_network. Running that also works great.

When I check docker network ls again I also see the second network it created:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5ac503033848        a_default           bridge              local  <== CREATED BY THE FIRST RUN
f0a42e17007b        a_my_network        bridge              local  <== CREATED BY THE SECOND RUN
1f65f9c91441        bridge              bridge              local
72fcb38f2060        host                host                local
b76cd7ef1ac9        none                null                local

I then started the second docker-compose file:

version: '3'

services:
  project_b:
    image: ubuntu
    command: >
      bash -c '
      apt update && apt install curl -y && 
      while true; do echo "Calling the container";  echo "BBBBBBB"; curl common_server:4444; sleep 10; done'
    networks:
     - a_my_network
networks:
  a_my_network:
    external: true

That also works. It can call the common_server from the first docker-compose file.

The first question I have: Although I define the network as my_network in the first file, it is called a_my_network by docker. Is there a way to define the network so that I can call it the same in both docker-compose files?

I then decided to remove those two networks using docker network prune, and start again. Unfortunately, when I now run the first file again I now get the following error:

$ docker-compose up
Creating network "a_my_network" with driver "bridge"
Starting a_common_server_1 ... error

ERROR: for a_common_server_1  Cannot start service common_server: network f0a42e17007bc0f352042f5394aef65be18bb12c7836e8864ecb734f83a421d7 not found

ERROR: for common_server  Cannot start service common_server: network f0a42e17007bc0f352042f5394aef65be18bb12c7836e8864ecb734f83a421d7 not found
ERROR: Encountered errors while bringing up the project.

So my second question: Why can I only start the first docker-compose file if I first create the a_default network by not explicitly defining a network?

Upvotes: 2

Views: 932

Answers (2)

David Maze
David Maze

Reputation: 159722

When you declare the network in the second file you can explicitly specify its name:.

version: '3.7'  # minimum of 3.5
networks:
  my_network:
    external: true
    name: a_my_network

As you note at the beginning, though, Compose creates a default network for you, and if you don't explicitly declare networks: for a container it will attach to default. You can reconfigure the default network however you'd like.

So probably what I'd do here is not declare networks: in the first docker-compose.yml file at all. In the second I'd make the default network point at the first file's default network, and also not configure networks: for containers.

networks:
  default:
    external: true
    name: a_default

Compose keeps track of what's going on primarily by using labels on objects. These are generally hidden from you but they're one of the things included in the very detailed docker inspect output. In your last example, if you manually docker network prune a network out from under Compose, it starts to get confused. On the other hand, if you just comment out the network you manually created and re-run docker-compose up, Compose should notice that it's created a network that's no longer needed and clean it up for you.

Upvotes: 2

bruegth
bruegth

Reputation: 701

You can alter the network name with the -p or --project-name flags or the COMPOSE_PROJECT_NAME environment variable.

And see here maybe: https://docs.docker.com/compose/networking/#use-a-pre-existing-network

Upvotes: 1

Related Questions