Marian Klühspies
Marian Klühspies

Reputation: 17717

Create networks automatically in Docker Compose

When using custom networks in Docker like

networks:
  default:
    external:
      name: service-tier

And try to run that, I´m getting the error

ERROR: Network service-tier declared as external, but could not be found. Please create the network manually using docker network create service-tier and try again.

Is it possible to create networks automatically with docker-compose or is there no other way than creating them manually first?

Upvotes: 57

Views: 176195

Answers (5)

rymo
rymo

Reputation: 3484

Do not conflate external: true with internal: false. To allow separate compose projects to share a network connection AND have that network be automatically created, simply specify a matching network name in each compose file.

internal

when set to true allow to create an externally isolated network

By default, networks are NOT internal and thus already provide external connectivity.

external

If set to true, external specifies that this network’s lifecycle is maintained outside of that of the application.

The external property refers to how the network is managed and does NOT describe its connectivity or lack thereof.

external: false:

  • is the default and can be omitted
  • allows a network to be auto-created as needed
  • will not throw an error if the network was previously auto-created by another running stack

name

Absent a specified name attribute, auto-created networks use the key prefixed with the project name. Explicitly setting the name prevents project scoping and allows for shared use.

Example

project1

services:
  db:
    networks:
      service_tier:
        aliases:
          - remotedb

networks:
  service_tier:
    name: service_tier

project2

services:
  web:
    networks:
      service_tier:

networks:
  service_tier:
    name: service_tier

Result

$ docker network ls

NETWORK ID     NAME                  DRIVER    SCOPE
ca564d4e76e6   bridge                bridge    local
6b4d2866afa8   host                  host      local
15fa57f54e0b   project1_default      bridge    local
a5eb24fc02b0   project2_default      bridge    local
d4b0a10c1385   service_tier          bridge    local
614c5864df80   none                  null      local

In this configuration the web service in project2 can reach the db service in project1 by using the host alias remotedb on the shared service_tier network.

Without name in the networks sections you would see separate project1_service_tier and project2_service_tier instead and communication would not be possible.

Upvotes: 16

Rob Evans
Rob Evans

Reputation: 2874

I also had this error:

Network "NETWORK_NAME" needs to be recreated - option "driver" has changed
   docker network ls
   docker network rm NETWORK_NAME
   docker-compose up

After removing the problem network and recreating it, things were fine.

Upvotes: 7

jcalabria
jcalabria

Reputation: 7

Run the following command: docker network create ddev_default

Upvotes: -12

helvete
helvete

Reputation: 2673

As @Grimmy correctly states, docker creates all mentioned networks, so these can be later referenced by running another compose file.

But, the defaultly generated network name is hardly practlical or robust. As it could turn out to be very long or the docker team changes their opinion on naming strategy.

But since compose file version 3.5 (means docker-compose version 1.18.0) one can name the network as pleases, so the overal solution is even more robust.

Please see the following snippets demonstrating on how to achieve this:

Compose file 1

version: '3.5'
services:
  svc-name:

    ...                          

    networks:
      - specific-network-name
    container_name: "exact-container-reference"

    ...

networks:
  specific-network-name:
    external: false
    name: specific-network-name

Compose file 2

version: '2'
services:

  svc-using-svc-name:

    ...

    networks:
      - default
      - specific-network-name
    external_links:
      - exact-container-reference

    ...

networks:
  specific-network-name:
    external: true

Upvotes: 45

Grimmy
Grimmy

Reputation: 4137

external is to use an existing network. If you want compose to make networks you simply do:

networks:
  network1:
  network2:

.. to instruct compose to make the networks. They will be named <compose-dir>-<network name> Verify the creation by using docker network ls.

You can also override the default network or specify more properties.

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1450

.. will override the default network setting MTU to 1450 (handy when the host have lower than 1500 mtu and path mtu discovery doesn't work properly). There are other bridge driver options.

external makes more sense when you want services in two compose setups to talk to each other or you have a manually created network.

Upvotes: 51

Related Questions