Defining a stack using Docker Compose files

The Docker Compose file schema has evolved from supporting client-side deployments on single Docker hosts to stack deployments across Docker Swarm. Different sets of attributes are relevant in different scenarios, and the tools enforce that. Docker Compose will ignore attributes that apply only to stack deployments, and Docker Swarm will ignore attributes that apply only to single-node deployments.

I can make use of multiple Compose files to exploit this, defining the basic setup of my application in one file, adding local settings in one override file and swarm settings in another override file. I've done that with the Compose files in the ch07-docker-compose folder. The core service definitions in docker-compose.yml are very simple now—they only include attributes that apply to every deployment mode. Even the reverse proxy definition for Traefik is simple:

reverse-proxy:
image: sixeyed/traefik:v1.7.8-windowsservercore-ltsc2019
networks:
- nd-net

In the docker-compose.local.yml override file, I add the attributes that are relevant when I'm developing the application on my laptop and deploying with Docker Compose. For Traefik, I need to configure the command to run and the ports to publish and mount a volume for the Docker Engine named pipe:

reverse-proxy:
command: --docker --docker.endpoint=npipe:////./pipe/docker_engine --api
ports:
- "80"
- "8080"
volumes:
- type: npipe
source: \.pipedocker_engine
target: \.pipedocker_engine

In the docker-compose.swarm.yml override file, I have the attribute to apply when I'm running in a clustered Docker Swarm environment—which could be a two-node swarm in test and a 200-node swarm in production; the Compose file would be the same. I set up the Traefik command to connect to the swarm manager using TCP, and I'm using secrets to store the TLS certificates in the swarm:

reverse-proxy:
command: --docker --docker.swarmMode --docker.watch --docker.endpoint=tcp://win2019-dev-02:2376
--docker.tls.ca=/certs/ca.pem --docker.tls.cert=/certs/cert.pem ...
ports:
- "80:80"
- "8080:8080"
secrets:
- source: docker-client-ca
target: C:certsca.pem
- source: docker-client-cert
target: C:certscert.pem
- source: docker-client-key
target: C:certskey.pem
deploy:
placement:
constraints:
- node.role == manager
The only part of this application manifest that isn't portable is the DNS name of my swarm manager, win2019-dev-02. I explained in Chapter 6, Organizing Distributed Solutions with Docker Compose, that you can't mount the named pipe in swarm mode yet, but it's coming soon. When that feature arrives, I can use the named pipe for Traefik in swarm mode in the same way as on a single Docker Engine, and my Compose files will work on any Docker cluster.

The pattern is the same for the rest of the services: there's a basic definition in docker: compose.yml, a set of overrides for developers in the local file, and an alternative set of overrides in the swarm file. The core Compose file can't be used on its own, because it doesn't have all the configuration specified, which is a different approach from Chapter 6Organizing Distributed Solutions with Docker Compose, where my Docker Compose file was set up for development. You can use whichever approach works best for you, but the advantage of this way is that the setup for every environment is captured in its own override file.

There are a couple of service options that are worth looking at in more detail. The REST API is defined in the core Compose file with just the image and network settings. The local override adds the labels used to register the API with the proxy, and it also captures the dependency on the database service:

nerd-dinner-api:
depends_on:
- nerd-dinner-db
labels:
- "traefik.frontend.rule=Host:api.nerddinner.local"

Swarm mode does not support the depends_on attribute. When you deploy a stack, there is no guarantee which order the services will start in. If your application components are resilient and have retry logic for any dependencies, then the service startup order doesn't matter. If your components are not resilient and crash when they can't access dependencies, then Docker will restart failed containers, and the application should be ready after a few retries.

Resilience is often missing from legacy applications, which assume that their dependencies are always available and able to respond immediately. This is not the case if you move to cloud services, and this is also true of containers. Docker will keep replacing failed containers, but you can add resilience even to legacy apps by building startup checks and health checks into the Dockerfile.

The swarm definition adds the secret and config setup, and there is also a difference in how the container labels are applied for Traefik:

nerd-dinner-api:
configs:
- source: nerd-dinner-api-config
target: C:dinner-apiconfigconfig.json
secrets:
- source: nerd-dinner-api-secrets
target: C:dinner-apiconfigsecrets.json
deploy:
replicas: 2
labels:
- "traefik.frontend.rule=Host:api.nerddinner.swarm"
- "traefik.port=80"

Configs and secrets only apply in swarm mode, but you can include them in any Compose file—Docker Compose will ignore them when you run on a single Docker Engine. The deploy section is also only for swarm mode, and this captures the infrastructure setup for the replicas. Here, I have a replica count of 2, meaning the swarm will run two containers for this service. I also have the labels for Traefik under the deploy section, which ensures the labels are applied to the containers, and not to the service itself.

Docker uses labels for annotating any type of object—volumes, nodes, services, secrets, containers, and any other Docker resource can have labels added or removed, and they are exposed as key-value pairs in the Docker Engine API. Traefik only looks for container labels, which are applied in swarm mode in the deploy section of the compose file. If you have labels directly under the service section, then they get added to the service and not to the containers. In this case, that would mean no labels on the containers, and so Traefik would not register any routes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.184.200