Configuring a 3-Node Docker Swarm & Deploying an Nginx Service

Nife Sofowoke
7 min readJun 3, 2024

--

This is a step-by-step guide on how to set up a 3-node Docker Swarm. This tutorial also includes a section on deploying a stack and running a Docker service by incorporating Docker Compose with the swarm.

What is a Docker Swarm?

Docker Swarm is a container orchestration tool used for managing a cluster of Docker nodes or engines in a single virtual system. Docker Swarm enables the deployment and management of a containerized application across multiple hosts, ensuring high availability, fault tolerance, rolling updates, container security, and scaling of the application. Therefore, we use docker swarm when we want to manage multiple containers across multiple hosts.

Some Docker terms explained

These are some frequently used Docker-related terms in this tutorial and what they mean:

  • node: an individual Docker Engine in the swarm that can be run on a single physical computer or cloud server. For this specific use case, since we run our Docker engine on an EC2 server, the instance can be referred to as a node.
  • swarm cluster: a group of nodes working together.
  • replica: an instance of a service. When creating a service, the number of replicas is specified. Replica in this context means the number of identical containers or tasks that should be running for that service. Each replica runs as a separate container on the nodes within the swarm. Having multiple replicas for a service provides high availability and scalability.
  • service: a unit of deployment that allows us to define what resources our application containers should contain, for example, the image, number of replicas, ports, network, volumes, and so on.

Prerequisites

  1. Docker environment setup. You can find the details on how to set up your Docker environment using an EC2 instance and VSCode in my previous Docker project. Reading the setup in the previous project would help you understand some steps I take when setting up the swarm below.
  2. Docker hub account
  3. Knowledge of basic Docker commands — docker pull, docker create, docker run, etc.

Step 1: Launch 2 additional Ubuntu Containers

  • To create a 3-node Swarm, we need three EC2 instances with Docker hosted on them. Since Docker is already hosted on one instance (from the first Docker setup in the previous project), we need to launch 2 additional instances. Note that we’ll be using the instance launched previously as the Manager node
  • I created a Cloudformation template like the previous project to launch 2 Ubuntu instances with Docker installed and configured on them.
  • Deploy the stack to launch the instances.
successful stack deployment
  • Verify that the 2 instances were deployed and are running.
  • Start up the original docker instance. I renamed it Swarm-Node1 for easy identification.
  • Edit the inbound security group for Node 1 to allow All TCP & UDP traffic from Node 2 & 3 instances security group. You should have something like this:

By doing this, we’re ensuring that the 3 nodes can communicate with each other and will be able to create a Swarm eventually.

Step 2: Edit SSH Configuration File

  • In VSCode, navigate to the SSH configuration file created when setting up the Docker environment.

Remote window icon >> Configure SSH Hosts >> ‘/users/…./.ssh/config

  • Add 2 new hosts (Node 2 & 3), the instance public IPs, and Keyfile path as shown below:
Host Node2/3
# IPv4 address will change with every restart
HostName <the publicIP of the Ubuntu instance launched>
User ubuntu
IdentityFile <path to keypair>
  • Save the file.

Step 3: SSH into the 3 Nodes

  • Open a terminal and navigate to where your keypair file is stored.
  • Split the terminal into 3 windows for the 3 nodes.
  • In the first terminal, SSH into the instance intended to be used as the manager node by using the command below:
ssh <hostname>

# in the config file, my hostname was 'Docker', so my command was:
ssh Docker

Totally unnecessary, but I changed the instance’s hostname (ubuntu@ip-172…) due to personal preference and for easy identification of my nodes.

To change it I used the command:

sudo hostnamectl set-hostname <new-hostname>

then exited out of the instance and sshed into it again for the change to take effect.

new host name
  • SSH into the remaining two instances/nodes in their respective terminals.

Now, we have our 3 nodes, all set up and running.

Note that our Swarm has not been created yet! Right now, we only have 3 instances configured and ready to be a Swarm.

Step 4: Create & Initialize Swarm

  • On the instance intended for use as the manager node, run the command below:
docker swarm init --advertise-addr <instance-private-IP4-address>

The command above advertises the private IPv4 address of the manager node so the 2 other nodes can join the Swarm as worker nodes. Doing this creates and initializes the Swarm, and it also enables communication between the 3 nodes.

swarm initialization

As seen in the image above, the output of the initialization command is a token for the remaining two nodes to join as workers.

  • Copy the token command and paste it into Nodes 2 & 3 terminals to complete the Swarm creation.
swarm creation

We’ve successfully created a 3-node swarm.

Step 5: Verify Swarm Availability

To verify the availability of the Swarm and make sure that it is set up correctly, run the command below in the manager node:

docker node ls

As seen in the image above, all 3 nodes are active.

We’ve successfully created a 3-node Swarm with 1 manager and 2 worker nodes!! Our Swarm configuration is complete, and we can now deploy services on the Swarm.

Deploying an Nginx service using Docker Swarm

Step 1: docker service create

  • On the master node of the Swarm, use the “docker service create” command to create a service with the specific options you’d like.

For this project, I would like to deploy a Nginx service named ‘my-nginx-service’ with the Nginx image on port 80:80 (Nginx’s default container port is 80) and start with one replica. Therefore, the command will be as below:

docker service create --name my-nginx-service -p 80:80 --replicas 1 nginx
nginx service creation

Step 2: Verify Service was created & is running

  • To verify that the Nginx service was created and is running, run the commands below:
# to verify the service was created
docker service ls

# to check the details of the service
docker service ps <service-name>

From the image above, we can confirm that the Nginx service has 1 replica, and is running on the manager node.

I also viewed the service with my browser (instance public IP address: 80)

Step 3: Scale the Service

  • To scale the service from 1 to 3 replicas, run the command below on the master node
docker service scale <service-name>=3
scaling nginx service

Step 4: Verify Service was Scaled

docker service ls

docker service ps <service-name>

As seen above, we’ve successfully scaled the nginx service to 3 replicas, and we have 1 replica each running on the manager node and 2 worker nodes, evenly spread out.

We’ve successfully created a service using Docker Swarm and scaled the service.

Clean Up

Remove the service created with the command below:

docker service rm <service-name>

# verify service was removed
docker service ls

Exit out of the instance in all 3 nodes by simply inputting ‘exit’

Stop the 3 instances in the EC2 dashboard

Conclusion

In this project we successfully:

  • created and configured a 3-node Docker Swarm
  • deployed an Nginx service with the Swarm
  • scaled the service from 1 to 3 replicas with each replica running on each node.

Thanks for reading and I hope it was of value to you!

Feel free to connect with me on LinkedIn or leave any constructive feedback you have in the comments.

--

--

Nife Sofowoke

A tech enthusiast on an exciting journey of transitioning into the field of Cloud/Devops Engineering.