Port your docker-compose project to Docker Swarm #
Planetary Quantum is based on Docker Swarm. The configuration for that is
very similar to docker-compose.yml
files, but it differs in some aspects:
Local Testing #
We recommend you enable Swarm on your local Docker installation:
$ docker swarm init
You can then deploy your existing docker-compose.yml
files via
$ docker stack deploy up -c docker-compose.yml --prune --with-registry-auth
Docker Swarm will then print warnings for all the unsupported elements.
Once you resolved all these (check out our hints below), chances are your project will work on Planetary Quantum out of the box.
See also: Making sure your Swarm Project works on Planetary Quantum.
Global options #
version
#
On Planetary Quantum, use
version: '3.8'
Unsupported service options #
build
#
Is an error on Swarm. Instead, build your containers on your CI system and push them to a private registry beforehand.
You can do that with your CI system, manually, or
with quantum-cli
.
Then, replace the build
with an
image: your-registry.example.org/your/image:some-version
You will need to set up up your private registry in Planetary Quantum, if you haven’t already.
container_name
#
Ignored on Swarm. Containers are named automatically, because there may be more than one per service (if you scale up the service).
depends_on
#
Ignored on Swarm. Swarm services restart when they fail by default (but
see restart
below), so in most setups, you can just remove depends_on
.
In the few cases where restarts are too costly, or otherwise not possible, we recommend using scripts like wait-for-it.sh in the startup code of containers, so the actual workload doesn’t start until all dependencies are reachable.
expose
#
Ignored on Swarm. Not needed, open ports are automatically exposed for the network(s) the container is in.
external_links
and links
#
Ignored on Swarm. Instead, put containers into a network, if they need to talk to each other.
If you don’t specify any networks:
, all services within a stack are in an
automatically created default network. That may not be what you want,
so it’s usually better to be explicit:
version: '3.8'
services:
some-server:
image: nginx
networks:
- my-internal-net
some-client:
image: alpine
command: curl some-server
networks:
- my-internal-net
networks:
my-internal-net:
To get services in different stacks to talk to each other, create a network first, via the Quantum Console:
- Choose “Networks” => “Add network”
- put in a name
- choose the “Overlay” driver
- and switch on “Enable manual container attachment”
You can then use that network in your stacks like so:
version: '3.8'
services:
foo:
image: nginx
networks:
- my-external-net
networks:
my-external-net:
external: true
name: my-external-net
DNS names #
Services in the same network can see each other under a couple of different
hostnames. For a service named my-service
, in a stack called my-stack
:
just
my-service
Do not use this name if the service is in a network that spans multiple stacks! You might have the same service name in two stacks, and then it's random which one it resolves to. On Quantum, watch out especially for services that are in the `public` network (the one Traefik uses). Even if you add your own stack-internal network, always connect to these services via a fully-qualified DNS name - see below
tasks.my-stack_my-service
Preferred, especially with external networks, because it always selects the correct service.
labels
#
Docker Swarm has two sets of labels - one on the containers, which are under
labels
, as in docker-compose. And another set on the services, which are
under deploy.labels
.
The distinction is only relevant if you use tools or services that read labels.
**Traefik labels on Planetary Quantum need to go into `deploy.labels`** - see also [Using the Traefik Load-balancer](/common-tasks/portainer-traefik/).
version: '3.8'
services:
foo:
image: nginx
deploy:
labels:
org.example.my-label: my-value
ports
#
Still supported on Docker Swarm, but often not needed. Use networks instead, for containers which should only be reachable to other containers.
For HTTP(S) connections to the outside world (including REST APIs, etc), use the Traefik Load-balancer.
restart
#
Ignored on Swarm. The default Docker Swarm behavior is equivalent to restart: always
.
restart: no
(the default with docker-compose) is
version: '3.8'
services
foo:
image: alpine
deploy:
restart_policy:
condition: none
Other options are available, including ways to specify delays and a maximum
number of retries before giving up - see
the Docker documentation on restart_policy
.
Other Swarm-incompatible service options #
All of these are ignored on Docker Swarm:
cap_add
andcap_drop
cgroup_parent
devices
network_mode
security_opt
tmpfs
userns_mode
Swarm-exclusive features #
Docker has a few guides for your consideration:
- Secrets, which are a way to store sensitive configs for the whole cluster.
- Configs work on a similar basis.
- Automatic Rollbacks are possible with Docker Swarm.
- Using “extension fields” and YAML anchors can make your stack yaml more organized.