Deploying a Docker Stack to Docker Swarm

This lab we will create a Docker Stack then deploy it to a Docker Swarm. It will also talk about some of the troubleshooting involved during the process.

What is Docker stack deploy?

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. The docker stack deploy command supports any Compose file of version “3.0” or above.

Docker swarm is a Clustering and orchestration tool. It is used for scheduling containers across multiple nodes. You can combine multiple nodes as a cluster and then send “docker run” command to this cluster.

Docker stack is a collection of services that make up an application in a specific environment. The extension of stack file is yaml (yml also).

Requirements:

  1. Personally, i’ll be using Ubuntu 20.04 server. I’ve had the most success using Ubuntu servers in the past with Docker.

2. Install Docker → https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04

3. Install Docker Compose → https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04

4. Run Docker Swarm →

docker swarm init

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:

docker service create --name registry --publish published=5000,target=5000 registry:2

Check its status with docker service ls:

Once it reads 1/1 under REPLICAS, it’s running. If it reads 0/1, it’s probably still pulling the image.

Check that it’s working with curl:

Create Application:

Github Repository: https://github.com/quiwest/stackdemo.git

Create a working directory. It can be any name of your choice.

$ mkdir stackdemo
$ cd stackdemo

Create a file called app.py in the project directory and paste this in:

Create a file called requirements.txt and paste these two lines in:

flask
redis

Create a file called Dockerfile and paste this in:

Create a file called docker-compose.yml and paste this in:

The 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.

Testing the app with Docker 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.

START NEW TERMINAL WITH SAME WORKING DIRECTORY.
This is because the containers are running, and we cant run the next few docker compose steps when the containers are stopped.

the containers are running, but if you want to run another command on this terminal you’ll have to stop the containers to do so.

Check that the app is running with docker-compose ps:

make sure the state says UP and not EXIT

You can test the app with curl:

Bring the app down: →

docker-compose down --volumes

To distribute the web app’s image across the swarm, it needs to be pushed to the registry you set up earlier.

docker-compose push

Deploy Stack to Swarm:

Create the stack with docker stack deploy:

docker stack deploy --compose-file docker-compose.yml stackdemo

This slight error might pop up when you run the the stack deploy. Stack is a cross-platform program for developing Haskell projects. It is intended for Haskellers both new and experienced.

Run again → docker stack deploy --compose-file docker-compose.yml stackdemo

Check that it’s running with docker stack services stackdemo:

Once it’s running, you should see 1/1 under REPLICAS for 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:

curl http://localhost:8000

Check your browser from your IP address and our swarm should appear.

Why doesn’t localhost:8000 work?

http://IP ADDRESS:8080 seems to work!

Bring the stack down with docker stack rm:

docker stack rm stackdemo

Bring the registry down with docker service rm:

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:

docker swarm leave --force

Thanks for checking this! Hopefully this helped somebody!

Feel free to contact me:

https://www.linkedin.com/in/quiwest/

→ quileswest@gmail.com

Junior DevOps Engineer