Deploy a stack to a swarm
En esta página
When running Docker Engine in swarm mode, you can use docker stack deploy to
deploy a complete application stack to the swarm. The deploy command accepts
a stack description in the form of a Compose file.
{{% include "swarm-compose-compat.md" %}}
To run through this tutorial, you need:
-
A Docker Engine running in Swarm mode. If you're not familiar with Swarm mode, you might want to read Swarm mode key concepts and How services work.
[!NOTE]
If you're trying things out on a local development environment, you can put your engine into Swarm mode with
docker swarm init.If you've already got a multi-node swarm running, keep in mind that all
docker stackanddocker servicecommands must be run from a manager node. -
A current version of Docker Compose.
Set up a Docker registry#
Because a swarm consists of multiple Docker Engines, a registry is required to distribute images to all of them. You can use the Docker Hub or maintain your own. Here's how to create a throwaway registry, which you can discard afterward.
-
Start the registry as a service on your swarm:
console $ docker service create --name registry --publish published=5000,target=5000 registry:2 -
Check its status with
docker service ls:```console $ docker service ls
ID NAME REPLICAS IMAGE COMMAND l7791tpuwkco registry 1/1 registry:2@sha256:1152291c7f93a4ea2ddc95e46d142c31e743b6dd70e194af9e6ebe530f782c17 ```
Once it reads
1/1underREPLICAS, it's running. If it reads0/1, it's probably still pulling the image. -
Check that it's working with
curl:```console $ curl http://127.0.0.1:5000/v2/
{} ```
Create the example application#
The app used in this guide is based on the hit counter app in the Get started with Docker Compose guide. It consists of a Python app which maintains a counter in a Redis instance and increments the counter whenever you visit it.
-
Create a directory for the project:
console $ mkdir stackdemo $ cd stackdemo -
Create a file called
app.pyin the project directory and paste this in:```python from flask import Flask from redis import Redis
app = Flask(name) redis = Redis(host='redis', port=6379)
@app.route('/') def hello(): count = redis.incr('hits') return 'Hello World! I have been seen {} times.\n'.format(count)
if name == "main": app.run(host="0.0.0.0", port=8000, debug=True) ```
-
Create a file called
requirements.txtand paste these two lines in:text flask redis -
Create a file called
Dockerfileand paste this in:```dockerfile
syntax=docker/dockerfile:1#
FROM python:3.4-alpine ADD . /code WORKDIR /code RUN pip install -r requirements.txt CMD ["python", "app.py"] ```
-
Create a file called
compose.yamland paste this in:yaml services: web: image: 127.0.0.1:5000/stackdemo build: . ports: - "8000:8000" redis: image: redis:alpineThe image for the web app is built using the Dockerfile defined above. It's also tagged with
127.0.0.1:5000- the address of the registry created earlier. This is important when distributing the app to the swarm.
Test the app with Compose#
-
Start the app with
docker compose up. This builds the web app image, pulls the Redis image if you don't already have it, and creates two containers.You see a warning about the Engine being in swarm mode. This is because Compose doesn't take advantage of swarm mode, and deploys everything to a single node. You can safely ignore this.
```console $ 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 are scheduled on the current node.
To deploy your application across the swarm, use
docker stack deploy.Creating network "stackdemo_default" with the default driver Building web ...(build output)... Creating stackdemo_redis_1 Creating stackdemo_web_1 ```
-
Check that the app is running with
docker compose ps:```console $ docker compose ps
Name Command State Ports
stackdemo_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp stackdemo_web_1 python app.py Up 0.0.0.0:8000->8000/tcp ```
You can test the app with
curl:```console $ curl http://localhost:8000 Hello World! I have been seen 1 times.
$ curl http://localhost:8000 Hello World! I have been seen 2 times.
$ curl http://localhost:8000 Hello World! I have been seen 3 times. ```
-
Bring the app down:
```console $ docker compose down --volumes
Stopping stackdemo_web_1 ... done Stopping stackdemo_redis_1 ... done Removing stackdemo_web_1 ... done Removing stackdemo_redis_1 ... done Removing network stackdemo_default ```
Push the generated image to the registry#
To distribute the web app's image across the swarm, it needs to be pushed to the registry you set up earlier. With Compose, this is very simple:
$ docker compose push
Pushing web (127.0.0.1:5000/stackdemo:latest)...
The push refers to a repository [127.0.0.1:5000/stackdemo]
5b5a49501a76: Pushed
be44185ce609: Pushed
bd7330a79bcf: Pushed
c9fc143a069a: Pushed
011b303988d2: Pushed
latest: digest: sha256:a81840ebf5ac24b42c1c676cbda3b2cb144580ee347c07e1bc80e35e5ca76507 size: 1372
The stack is now ready to be deployed.
Deploy the stack to the swarm#
-
Create the stack with
docker stack deploy:```console $ docker stack deploy --compose-file compose.yaml stackdemo
Ignoring unsupported options: build
Creating network stackdemo_default Creating service stackdemo_web Creating service stackdemo_redis ```
The last argument is a name for the stack. Each network, volume and service name is prefixed with the stack name.
-
Check that it's running with
docker stack services stackdemo:```console $ docker stack services stackdemo
ID NAME MODE REPLICAS IMAGE orvjk2263y1p stackdemo_redis replicated 1/1 redis:3.2-alpine@sha256:f1ed3708f538b537eb9c2a7dd50dc90a706f7debd7e1196c9264edeea521a86d s1nf0xy8t1un stackdemo_web replicated 1/1 127.0.0.1:5000/stackdemo@sha256:adb070e0805d04ba2f92c724298370b7a4eb19860222120d43e0f6351ddbc26f ```
Once it's running, you should see
1/1underREPLICASfor both services. This might take some time if you have a multi-node swarm, as images need to be pulled.As before, you can test the app with
curl:```console $ curl http://localhost:8000 Hello World! I have been seen 1 times.
$ curl http://localhost:8000 Hello World! I have been seen 2 times.
$ curl http://localhost:8000 Hello World! I have been seen 3 times. ```
With Docker's built-in routing mesh, you can access any node in the swarm on port
8000and get routed to the app:console $ curl http://address-of-other-node:8000 Hello World! I have been seen 4 times. -
Bring the stack down with
docker stack rm:```console $ docker stack rm stackdemo
Removing service stackdemo_web Removing service stackdemo_redis Removing network stackdemo_default ```
-
Bring the registry down with
docker service rm:console $ docker service rm registry -
If you're just testing things out on a local machine and want to bring your Docker Engine out of Swarm mode, use
docker swarm leave:```console $ docker swarm leave --force
Node left the swarm. ```