A service can be either created as part of a stack, or directly using the Docker CLI. Let's first look at a sample stack file that defines a single service:
version: "3.5"
services:
whoami:
image: training/whoami:latest
networks:
- test-net
ports:
- 81:8000
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
labels:
app: sample-app
environment: prod-south
networks:
test-net:
driver: overlay
In the preceding example we see what the desired state of a service called whoami is:
- It is based on the image training/whoami:latest
- Containers of the service are attached to the network test-net
- The container port 8000 is published to port 81
- It is running with six replicas (or tasks)
- During a rolling update, the individual tasks are updated in batches of two, with a delay of 10 seconds between each successful batch
- The service (and its tasks and containers) is assigned the two labels app and environment, with the values sample-app and prod-south respectively
There are many more settings that we could define for a service, but the preceding ones are some of the more important ones. Most settings have meaningful default values. If, for example, we do not specify the number of replicas, then Docker defaults it to 1. The name and image of a service are of course mandatory. Note that the name of the service must be unique in the swarm.
To create the preceding service, we use the docker stack deploy command. Assuming that the file in which the preceding content is stored is called stack.yaml, we have:
$ docker stack deploy -c stack.yaml sample-stack
Here, we have created a stack called sample-stack that consists of one service, whoami. We can list all stacks on our swarm, whereupon we should get this:
$ docker stack ls
NAME SERVICES
sample-stack 1
If we list the services defined in our swarm, we get the following output:
In the output, we can see that currently we have only one service running, which was to be expected. The service has an ID. The format of the ID, contrary, what you have used so far for containers, networks, or volumes, is alphanumeric. We can also see that the name of the service is a combination of the service name we defined in the stack file and the name of the stack, which is used as a prefix. This makes sense, since we want to be able to deploy multiple stacks (with different names) using the same stack file into our swarm. To make sure that service names are unique, Docker decided to combine service name and stack name.
In the third column we see the mode, which is replicated. The number of replicas is shown as 6/6. This tells us that six out of the six requested replicas are running. This corresponds to the desired state. In the output we also see the image that the service uses and the port mappings of the service.