Deploy Swarm Services with the new docker `stack` and a compose file!
On of the new additions of Docker 1.13 is the ability to use compose files to deploy swarm mode services!
This means that we can use docker-compose files to provision Swarm services.
That also means that we do not need anymore to type all the long docker service create
commands.
A long list of docker service create commands would be simply replaced by a command like the below:
docker stack deploy --compose-file=docker-compose.yml my_stack
In this blog post, we will see that in action and discuss what is covered and what still lacks.
Life before Docker stack deploy
Or precisely, before docker stack deploy --compose-file <Path to a Compose file>
we had to type a lot and maintain a shell script to start our services accross the Swarm.
What made things worse, is that before the addition of this command, as developers, we loved the docker-compose command to deploy a stack on our machines. But as you know, docker-compose couldn't benefit from all the nodes of the swarm cluster. It gave us a warning like the below:
docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use the bundle feature of the Docker experimental build.
More info:
https://docs.docker.com/compose/bundles
So even if you had a compose-file for local testing, you would have to prepare a set of commands to create the service on the Swarm and align those! Talk about technical debt...
Let's take a simple example where we want to deploy two service to monitor the swarm.
These two service I tend to always create first thing on my Swarms are the Visualizer and Portainer. Here is how I used to do so:
docker service create \
--publish 9000:9000 \
--name portainer \
--constraint=node.role==manager \
--mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
portainer/portainer
docker service create \
--publish=9090:8080 \
--limit-cpu 0.5 \
--name=viz \
--constraint=node.role==manager \
--mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
dockersamples/visualizer
Life after Docker stack deploy
Let's now deploy our monitoring
stack again, but this time with the new shiny way:
curl -o docker-compose-stack-monitoring.yml \
https://raw.githubusercontent.com/jmkhael/compose-samples/master/docker-compose-stack-monitoring.yml
docker stack deploy -c docker-compose-stack-monitoring.yml monitoring
The first command downloaded the Compose file docker-compose-stack-monitoring.yml from the jmkhael/compose-samples repository.
The second command creates the services which form what I called the monitoring stack.
Note from the below output that it does incrementally handle new service:
Creating service monitoring_viz
Updating service monitoring_portainer (id: jbt006a7yoi8t0ok941b358k2)
If you check the created services, you'll see portainer and visualizer:
docker service ls
ID NAME MODE REPLICAS IMAGE
jbt006a7yoi8 monitoring_portainer replicated 1/1 portainer/portainer:latest
wqfb3odzmnfh monitoring_viz replicated 1/1 dockersamples/visualizer:latest
that's neat!
The docker-compose-stack-monitoring.yml file look like this:
version: '3'
services:
portainer:
image: portainer/portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 9000:9000
deploy:
placement:
constraints: [node.role == manager]
viz:
image: dockersamples/visualizer
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
placement:
constraints: [node.role == manager]
ports:
- 9090:8080
Note that the docker-compose file uses the version 3, introduced with Docker 1.13. (Check the schema here)
You can use some nice configurations under the deploy section such as deployment mode (replicated or global), replicas count (replicas: 3) or labels...
deploy:
mode: replicated
replicas: 2
labels: [APP=CONQUER_UNIVERSE]
Is everything covered?
TL;DR:
The short answer is of course, No.
The longer answer is around these lines:
Networks
No support for attachable networks yet in the docker-compose v3.
Extends not supported
You cannot use the extends keyword. But there is a quick workaround for that. You'd need to resolve the docker-compose keyword by issuing:
docker-compose config > docker-compose-resolved.yml
Unsupported docker-compose v2 keywords
The below keywords are still not supported.
- "build",
- "cap_add",
- "cap_drop",
- "cgroup_parent",
- "devices",
- "dns",
- "dns_search",
- "domainname",
- "external_links",
- "ipc",
- "links",
- "mac_address",
- "network_mode",
- "privileged",
- "read_only",
- "restart",
- "security_opt",
- "shm_size",
- "stop_signal",
- "tmpfs"
That's it for this post. Now go deploy some stacks!