Skip to main content

Docker Swarm

For the foreseable future we will be using docker swarm to manage our servers. Below is a documentation of how to set it up and add nodes when needed.

Setup Docker Swarm

To begin we need to define a manager node by running the following command on the main server

docker swarm init --advertise-addr <server_ip_here> --default-addr-pool "14.0.0.0/20"
note

For a single node swarm. We do not need this option --advertise-addr <server_ip_here>.

note

The default-addr-pool is the range of IP addresses that are available for automatic assignment to containers. Use the value of 14.0.0.0/20 for the default pool, unless you have a specific reason to change it.

This command prints out a token for use when adding other nodes to the swarm.

Joining the Swarm

To add another node/server to the manager node for horizontal scaling, we run the following command

docker swarm join --token token_from_previeous_step <ip_of_manager_node:port>.

If you no longer have the token, you can get it again by logging into the manager node and running the following command.

docker swarm join-token worker

Building Images

On staging we can continue manually building our images before using the swarm to deploy the app. This way we don’t store more images than necessary on the ECR.

For production however, we can configure the CI to build, tag, and push new images to the ECR.

tip

Remember to increase the version of updated services before building/pushing images.

Using SemVer(x.y.Z).

For staging changes/deployment increment Z on both staging and build compose files.

For production deployment increment y and reset Z to 0 staging, build, prod compose files

Deploying Services to the Swarm

There are multiple ways to create a service on docker swarm, using docker service and using docker stack. We will be making use of docker stack here inorder to reuse our existing compose files.

We have several compose files for different purposes.

  • docker-compose.build.yml: This file is meant for building images for all our services. Whether on the server(staging), or on the CI(for production images).
  • docker-compose.prod.yml: This is for deploying the stack in production docker stack deploy -c docker-compose.prod.yml sh-project
  • docker-compose.staging.yml: This is for deploying the stack on staging docker stack deploy -c docker-compose.staging.yml sh-project
  • docker-compose.preview-build.yml: This is for building images on the test instance docker-compose -f docker-compose.preview-build.yml build
  • docker-compose.preview.yml: This is for deploying the stack on the test instance docker stack deploy -c docker-compose.preview.yml sh-project
  • docker-compose.yml: This is for local development

Environment Setup

In any environment where the use private registry is needed, there are a couple of things that we need to do first.

  • Install awscli on the server if we haven't yet. sudo apt-get update && sudo apt install awscli.
  • Configure iam role to access ecr in readonly mode. Our instances already have full admin access so we can skip this step
  • Do docker login aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 567193262400.dkr.ecr.us-east-2.amazonaws.com
  • Start docker-swarm. docker stack deploy -c docker-compose.staging.yml sh-project --with-registry-auth
note

Without the docker login and the --with-registry-auth flag, swarm won't be able to pull private images.

Deploy the Stack

To deploy docker stack. We run the following command

docker stack deploy -c docker-compose.prod.yml sh-project

Where sh-project is the name of the stack. For consistency, let's keep the stack name the same across all our environments.

Managing the Swarm

Below are a list of commands to manage day to day operations on the swarm.

List services

docker service ls

Or

docker stack services ls

In the following examples sh-project_ds in the name of the service we are operating on. Keep in mind that service names are prefixed by the name of the stack.

Scale a Service

To Increase the number of instances of a particular service we run

docker service scale sh-project_ds=5

View Logs

docker service logs sh-project_ds

Delete a service

docker service rm sh-project_ds

Delete a stack

docker stack rm sh-project

This removes all the services in the stack, then delete the stack itself

Update a service

This could happen during deployment and we want to deploy the newly built service.

docker service update sh-project_ds:version
note

Remember to increment the version number in the docker-compose files before building and updating.

Rollback an Update

docker service rollback sh-project_ds

Keep in mind that updates can be version change as well scaling updates e.t.c.

Add New Service to the Swarm

When we a new service to our docker-compose.*yml, to make it part of our swarm we will need to use the deploy command. This updates existing services in the stack if their configurations(replicates, versions e.t.c) have changed or skips them, and creates the newly introduced service in our stack.