Skip to content
Distr
Book DemoStart free trialLogin

Docker Multi App Networking

Services in one Compose file reach each other by their service names. Services in different applications don’t, even on the same deployment target, because the Docker controller runs every deployment as a Compose project of its own (distr-<short-deployment-id>) with its own default network.

To connect them, one application creates a Docker network and the others join it. The example at the end does this for a database and a backend that are deployed separately.

Create a Docker application in Distr with the following Compose file. It exists only to create the shared network.

network/docker-compose.yaml
services:
network:
image: 'registry.k8s.io/pause:3.10'
restart: unless-stopped
networks:
- acme-shared
networks:
acme-shared:
name: acme-shared
  • networks.acme-shared.name fixes the network’s name. Without it, Compose puts the project name in front. That name differs for every deployment, so the others would not find the network. Replace acme-shared with a name unique to your application.
  • network is a placeholder. Compose won’t start a project that has no services, so the application needs one. The pause image does nothing and uses almost no resources.

One of your other applications can create the network too, the way the proxy does in Docker Blue-Green Deployments. The advantage of a separate application is that you can update or undeploy any of the others without touching the network.

Step 2: Join the network from your applications

Section titled “Step 2: Join the network from your applications”

The other applications declare the network as external, so Compose uses the existing network rather than creating its own. Add it to every service that has to reach another deployment:

docker-compose.yaml
services:
my_service:
# ...
networks:
- acme-shared
networks:
acme-shared:
external: true

Deploy all applications on the same deployment target, the network application before the others. For the first deployment, follow Create a Deployment. For the others, use + Deploy App on the deployment target card.

If you deploy another application first, it fails with network acme-shared declared as external, but could not be found. The controller retries every cycle, so the deployment starts by itself once the network exists.

This example connects the backend of hello-distr, our example application, to a PostgreSQL database deployed separately. Create a Docker application from each of the following Compose files and name them Network, Database and Backend. The backend connects to the database as acme-db. Both read the password from a Distr secret, so it never appears in a deployment configuration.

services:
network:
image: 'registry.k8s.io/pause:3.10'
restart: unless-stopped
networks:
- acme-shared
networks:
acme-shared:
name: acme-shared

Deploy the Network, then the Database and the Backend. The backend’s health check queries the database, so once the Database and Backend deployments are Healthy, the connection works. The Network deployment has no health check and stays Running. http://<host>/latest-message then answers with hello distr!.

Address other deployments by a network alias

Section titled “Address other deployments by a network alias”

On the shared network, every container answers to its network aliases and to its service name. Service names tend to be generic, like postgres or backend. Two deployments can easily use the same one. Docker then resolves the name to both containers in random order. Each request ends up at either of them.

  • Give every service that other deployments connect to an alias under networks.<name>.aliases (like acme-db) and connect only through the alias.
  • If one application is deployed more than once on a deployment target, build the alias from a deployment variable, for example acme-db-${INSTANCE}, so each deployment has its own. Do the same for published host ports, since only one deployment can bind the Backend’s port 80, for example ${HTTP_PORT}:5000.

Leave services that no other deployment needs off the shared network.

When a new version of the network application changes the network, for example by adding a label, a driver option or a subnet, Compose tries to recreate it. Docker can’t remove a network that other deployments are still connected to, so the update fails with network acme-shared has active endpoints. Settle the definition before the first deployment and keep it the same in every later version.