summaryrefslogtreecommitdiff
path: root/devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html
new repository
Diffstat (limited to 'devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html')
-rw-r--r--devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html127
1 files changed, 127 insertions, 0 deletions
diff --git a/devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html b/devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html
new file mode 100644
index 00000000..ee0e74c9
--- /dev/null
+++ b/devdocs/docker/engine%2Fswarm%2Fstack-deploy%2Findex.html
@@ -0,0 +1,127 @@
+<h1>Deploy a stack to a swarm</h1>
+
+<p>When running Docker Engine in swarm mode, you can use <code class="language-plaintext highlighter-rouge">docker stack deploy</code> to deploy a complete application stack to the swarm. The <code class="language-plaintext highlighter-rouge">deploy</code> command accepts a stack description in the form of a <a href="../../../compose/compose-file/compose-file-v3/index">Compose file</a>.</p> <p>The <code class="language-plaintext highlighter-rouge">docker stack deploy</code> command supports any Compose file of version “3.0” or above. If you have an older version, see the <a href="../../../compose/compose-file/compose-versioning/index#upgrading">upgrade guide</a>.</p> <p>To run through this tutorial, you need:</p> <ol> <li> <p>A Docker Engine running in <a href="../swarm-mode/index">swarm mode</a>. If you’re not familiar with swarm mode, you might want to read <a href="../key-concepts/index">Swarm mode key concepts</a> and <a href="../how-swarm-mode-works/services/index">How services work</a>.</p> <blockquote> <p><strong>Note</strong></p> <p>If you’re trying things out on a local development environment, you can put your engine into swarm mode with <code class="language-plaintext highlighter-rouge">docker swarm init</code>.</p> <p>If you’ve already got a multi-node swarm running, keep in mind that all <code class="language-plaintext highlighter-rouge">docker stack</code> and <code class="language-plaintext highlighter-rouge">docker service</code> commands must be run from a manager node.</p> </blockquote> </li> <li> <p>A current version of <a href="../../../compose/install/index">Docker Compose</a>.</p> </li> </ol> <h2 id="set-up-a-docker-registry">Set up a Docker registry</h2> <p>Because a swarm consists of multiple Docker Engines, a registry is required to distribute images to all of them. You can use the <a href="https://hub.docker.com">Docker Hub</a> or maintain your own. Here’s how to create a throwaway registry, which you can discard afterward.</p> <ol> <li> <p>Start the registry as a service on your swarm:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker service create --name registry --publish published=5000,target=5000 registry:2
+</pre></div> </li> <li> <p>Check its status with <code class="language-plaintext highlighter-rouge">docker service ls</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker service ls
+
+ID NAME REPLICAS IMAGE COMMAND
+l7791tpuwkco registry 1/1 registry:2@sha256:1152291c7f93a4ea2ddc95e46d142c31e743b6dd70e194af9e6ebe530f782c17
+</pre></div> <p>Once it reads <code class="language-plaintext highlighter-rouge">1/1</code> under <code class="language-plaintext highlighter-rouge">REPLICAS</code>, it’s running. If it reads <code class="language-plaintext highlighter-rouge">0/1</code>, it’s probably still pulling the image.</p> </li> <li> <p>Check that it’s working with <code class="language-plaintext highlighter-rouge">curl</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ curl http://localhost:5000/v2/
+
+{}
+</pre></div> </li> </ol> <h2 id="create-the-example-application">Create the example application</h2> <p>The app used in this guide is based on the hit counter app in the <a href="../../../compose/gettingstarted/index">Get started with Docker Compose</a> guide. It consists of a Python app which maintains a counter in a Redis instance and increments the counter whenever you visit it.</p> <ol> <li> <p>Create a directory for the project:</p> <div class="highlight"><pre class="highlight" data-language="">$ mkdir stackdemo
+$ cd stackdemo
+</pre></div> </li> <li> <p>Create a file called <code class="language-plaintext highlighter-rouge">app.py</code> in the project directory and paste this in:</p> <div class="highlight"><pre class="highlight" data-language="">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)
+</pre></div> </li> <li> <p>Create a file called <code class="language-plaintext highlighter-rouge">requirements.txt</code> and paste these two lines in:</p> <pre>flask
+redis
+</pre> </li> <li> <p>Create a file called <code class="language-plaintext highlighter-rouge">Dockerfile</code> and paste this in:</p> <div class="highlight"><pre class="highlight" data-language=""># syntax=docker/dockerfile:1
+FROM python:3.4-alpine
+ADD . /code
+WORKDIR /code
+RUN pip install -r requirements.txt
+CMD ["python", "app.py"]
+</pre></div> </li> <li> <p>Create a file called <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> and paste this in:</p> <pre>version: "3.9"
+
+services:
+ web:
+ image: 127.0.0.1:5000/stackdemo
+ build: .
+ ports:
+ - "8000:8000"
+ redis:
+ image: redis:alpine
+</pre> <p>The image for the web app is built using the Dockerfile defined above. It’s also tagged with <code class="language-plaintext highlighter-rouge">127.0.0.1:5000</code> - the address of the registry created earlier. This is important when distributing the app to the swarm.</p> </li> </ol> <h2 id="test-the-app-with-compose">Test the app with Compose</h2> <ol> <li> <p>Start the app with <code class="language-plaintext highlighter-rouge">docker-compose up</code>. This builds the web app image, pulls the Redis image if you don’t already have it, and creates two containers.</p> <p>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.</p> <pre>$ 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
+</pre> </li> <li> <p>Check that the app is running with <code class="language-plaintext highlighter-rouge">docker-compose ps</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ 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-&gt;8000/tcp
+</pre></div> <p>You can test the app with <code class="language-plaintext highlighter-rouge">curl</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ 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.
+</pre></div> </li> <li> <p>Bring the app down:</p> <div class="highlight"><pre class="highlight" data-language="">$ 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
+</pre></div> </li> </ol> <h2 id="push-the-generated-image-to-the-registry">Push the generated image to the registry</h2> <p>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:</p> <div class="highlight"><pre class="highlight" data-language="">$ 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
+</pre></div> <p>The stack is now ready to be deployed.</p> <h2 id="deploy-the-stack-to-the-swarm">Deploy the stack to the swarm</h2> <ol> <li> <p>Create the stack with <code class="language-plaintext highlighter-rouge">docker stack deploy</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker stack deploy --compose-file docker-compose.yml stackdemo
+
+Ignoring unsupported options: build
+
+Creating network stackdemo_default
+Creating service stackdemo_web
+Creating service stackdemo_redis
+</pre></div> <p>The last argument is a name for the stack. Each network, volume and service name is prefixed with the stack name.</p> </li> <li> <p>Check that it’s running with <code class="language-plaintext highlighter-rouge">docker stack services stackdemo</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ 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
+</pre></div> <p>Once it’s running, you should see <code class="language-plaintext highlighter-rouge">1/1</code> under <code class="language-plaintext highlighter-rouge">REPLICAS</code> for both services. This might take some time if you have a multi-node swarm, as images need to be pulled.</p> <p>As before, you can test the app with <code class="language-plaintext highlighter-rouge">curl</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ 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.
+</pre></div> <p>Thanks to Docker’s built-in routing mesh, you can access any node in the swarm on port 8000 and get routed to the app:</p> <div class="highlight"><pre class="highlight" data-language="">$ curl http://address-of-other-node:8000
+Hello World! I have been seen 4 times.
+</pre></div> </li> <li> <p>Bring the stack down with <code class="language-plaintext highlighter-rouge">docker stack rm</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker stack rm stackdemo
+
+Removing service stackdemo_web
+Removing service stackdemo_redis
+Removing network stackdemo_default
+</pre></div> </li> <li> <p>Bring the registry down with <code class="language-plaintext highlighter-rouge">docker service rm</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker service rm registry
+</pre></div> </li> <li> <p>If you’re just testing things out on a local machine and want to bring your Docker Engine out of swarm mode, use <code class="language-plaintext highlighter-rouge">docker swarm leave</code>:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker swarm leave --force
+
+Node left the swarm.
+</pre></div> </li> </ol>
+<p><a href="https://docs.docker.com/search/?q=guide">guide</a>, <a href="https://docs.docker.com/search/?q=swarm%20mode">swarm mode</a>, <a href="https://docs.docker.com/search/?q=composefile">composefile</a>, <a href="https://docs.docker.com/search/?q=stack">stack</a>, <a href="https://docs.docker.com/search/?q=compose">compose</a>, <a href="https://docs.docker.com/search/?q=deploy">deploy</a></p>
+<div class="_attribution">
+ <p class="_attribution-p">
+ &copy; 2019 Docker, Inc.<br>Licensed under the Apache License, Version 2.0.<br>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.<br>Docker, Inc. and other parties may also have trademark rights in other terms used herein.<br>
+ <a href="https://docs.docker.com/engine/swarm/stack-deploy/" class="_attribution-link">https://docs.docker.com/engine/swarm/stack-deploy/</a>
+ </p>
+</div>