1. Overview / Introduction
We have already seen what the
docker-compose can be used for. The
docker stack command is very similar to docker, however some key differences remain.
A Docker Stack is the top of the hierarchy of distributed applications. It is a group of interrelated services that share dependencies. Orchestration and scaling of these services is also possible by using compose files (.yml).
2. Key Differences between docker stack and docker-compose
- Programming Language
- Description file version
- Swarm dependency
Docker-compose in based on python while docker stack comes with a standard docker installation. Chances are docker-composer might be deprecated and docker stack will be long-term supported.
Docker-compose supports version 2 and upwards of the .yml compose files. Docker stack requires at least version 3.
Docker stack requires a swarm to be initialized before an application can be deployed
Note: A Docker swarm is a group of machines that are running the Docker engine and joined into a docker cluster.
2. Usage comparison by example
Let’s reuse a previous example compose file that creates a server-client dependence container orchestration.
version: "2" services: server: image: pushcommit/myveryfirstimageserver client: image: pushcommit/myveryfirstimageclient
If we run
docker-compose up we see the two services communicating until we stop it. Interestingly, there is a warning that highlights that docker-compose cannot be used to deploy to a swarm.
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 `docker stack deploy`.
Starting uservirt_client_1 …
Starting uservirt_server_1 …
Starting uservirt_client_1 … done
Attaching to uservirt_server_1, uservirt_client_1
server_1 | Server listening on 80
server_1 | /
client_1 | Hello World!
server_1 | /
client_1 | Hello World!
^CGracefully stopping… (press Ctrl+C again to force)
Stopping uservirt_client_1 … done
Stopping uservirt_server_1 … done
There are the two containers running our services:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78286b6969f2 pushcommit/myveryfirstimageclient “/bin/sh -c ‘node /d…” 11 minutes ago Up 10 seconds uservirt_client_1
140b444634c3 pushcommit/myveryfirstimageserver “/bin/sh -c ‘node /d…” 11 minutes ago Up 11 seconds uservirt_server_1
A network is set up automatically with a preset naming convention.
NETWORK ID NAME DRIVER SCOPE
aca201165a06 uservirt_default bridge local
2.2 Docker stack
As said before, we need to state a version 3 in our .yml compose file. After that change, if we assume our docker machine is not in swarm mode yet, we can deploy our app by the two commands:
docker swarm init
docker stack deploy -c docker-compose.yml mystackapp
We see, that for our stack a netork and two services were created.
Creating service mystackapp_server
Creating service mystackapp_client
Now, we can inspect our app with
docker stack ps mystackapp and so on or use portainer.io. Our client and server are now running as a service instead of being containers.
In general, you can say that it is preferable to use
docker stack since
docker-compose will be deprecated. However, the ease of use and not needing to run the docker engine in swarm mode might make
docker-compose still favorable. Also
docker-compose supports .yml compose file version 2.
Except for that there are many similarities in functionality but docker stack is probably the better choice if later scaling (with swarms) is necessary.