DEV Community

Cover image for Docker Swarm - Installing a 5-tier Web App
Joey Ohannesian
Joey Ohannesian

Posted on


Docker Swarm - Installing a 5-tier Web App

🐋 Docker Swarm? Why Not K8s?

Docker Swarm is simple. It comes with Docker and has exactly what we need for this project...

We want to create a simple 5-service web application.

In order to understand why we’re using Docker instead of K8s here, we really need to ask ourselves what we really want out of a container orchestrator.

In other words, what do we need?

Similar to Maslow’s Hierarchy of Needs in an interesting way

Similar to Maslow’s Hierarchy of Needs in an interesting way

Our Needs

  • Orchestrator to relaunch a container if the container goes down
  • Light load balancer between two nodes for our voting app
  • Persistent storage
  • Frontend/backend network

Goal, Success Criteria, & Prereqs

Argentina won the FIFA World Cup on 12/18

Argentina won the FIFA World Cup on 12/18



The goal for this project is to create a 5-service web app that’s distributed amongst 5 nodes.

✅Success Criteria

Success is determined when the following is achieved.

  • Visitors can visit the IP address of the website successfully and can:
    • View webpage
    • Interact with web app, cast, and change vote
  • Administrator can view results in real-time


  • All images are on Docker Hub, so you should use editor to craft your commands locally, then paste them into swarm shell (at least that's how I'd do it)
  • a backend and frontend overlay network are needed. Nothing different about them other than that backend will help protect database from the voting web app. (similar to how a VLAN setup might be in traditional architecture)
  • The database server should use a named volume for preserving data. Use the new -mount format to do this: -mount type=volume,source=db-data,target=/var/lib/postgresql/data

Services (names below should be service names)

  • vote
    • bretfisher/examplevotingapp_vote
    • web frontend for users to vote dog/cat
    • ideally published on TCP 80. Container listens on 80
    • on frontend network
    • 2+ replicas of this container
  • redis
    • redis:3.2
    • key-value storage for incoming votes
    • no public ports
    • on frontend network
  • worker
    • bretfisher/examplevotingapp_worker
    • backend processor of redis and storing results in postgres
    • no public ports
    • on frontend and backend networks
    • 1 replica
  • db
    • postgres:9.4
    • one named volume needed, pointing to /var/lib/postgresql/data
    • on backend network
    • 1 replica
    • remember set env for password-less connections -e POSTGRES_HOST_AUTH_METHOD=trust
  • result

    • bretfisher/examplevotingapp_result
    • web app that shows results
    • runs on high port since just for admins (lets imagine)
    • so run on a high port of your choosing (I choose 5001), container listens on 80
    • on backend network
    • 1 replica

1️⃣ Create a 3 Node Swarm Cluster

Because this is not a tutorial on how to create a Swarm cluster, I will not be covering how to create one here. To do so, please follow the link located within the prerequisites or by clicking the link here. You will have to complete steps 1 - 5.

Successful creation of a 3-node cluster

A successful 3-node cluster looks like this after typing docker node ls .

2️⃣ Crafting the Docker Commands

There will be two parts to this step. The first will involve creating the frontend and backend overlay networks. These allow the nodes to connect and communicate with each other, and most importantly, load balance once traffic hits the node.

There will be a total of five Docker commands when it comes to our services. I will write each one, then explain what each part means.

Be warned, this step is dense!

Balance is important

⚡Part 1 - The Networks

Create Two Overlay Networks

docker network create \
    --driver overlay \

&& docker network create \
    --driver overlay \
Enter fullscreen mode Exit fullscreen mode
Commands Broken Down

docker network create - Create a new network

--driver overlay - Specifically create an overlay network

frontend or backend - The name of our network(s)

All networks after creating the front and backend overlay networks

🧑‍🔧Part 2 - The Services

Create the Vote Webapp Frontend

docker service create \
    --name vote-app \
    -p 80:80 \
    --network frontend \
    --replicas 2 \
Enter fullscreen mode Exit fullscreen mode
Commands Broken Down

docker service create - Create a new service for Swarm

--name vote-app - Name the service *****vote-app*****

-p 80:80 - Publish & expose port 80 for outgoing/incoming traffic

--network frontend - Attach the service to the frontend network

--replicas 2 - Create 2 replicas within the Swarm

bretfisher/examplevotingapp_vote - The web app container image

Create the Database

Create a password using a secret. This is the most secure way of passing a password to the database. The only thing you need to do is clear your terminal log with history -c after creating your password!

printf "enter-pass-here" | docker secret create db_pass -

printf "enter-pass-here" - Create the password string that will be used

docker secret create - Create a secret in docker

my_secret_data - The name of the secret

- - Copies enter-pass-here into my_secret_data

docker service create \
    --name db \
    --network backend \
    --secret my_secret_data \
    -e POSTGRES_PASSWORD_FILE=/run/secrets/my_secret_data \
    --mount type=volume,source=db-data,target=/var/lib/postgresql/data \
Enter fullscreen mode Exit fullscreen mode
Commands Broken Down

--secret my_secret_data - Use the secret my_secret_data

-e POSTGRES_PASSWORD_FILE=/run/secrets/db_pass - Tell postgres to use the secret, my_secret_data

-e POSTGRES_HOST_AUTH_METHOD=trust - Allows all users to connect

--mount type=volume,source=db-data,target=/var/lib/postgresql/data - Stores the data persistently in case the DB container gets restarted

Create the redis Service

docker service create --name redis --network frontend --replicas 1 redis:3.2

Create the Worker

docker service create --name worker --network frontend --network backend --replicas 1 bretfisher/examplevotingapp_worker

Create Results

docker service create --name result --network backend --replicas 1 -p 5001:80 bretfisher/examplevotingapp_result

5 services running successfully with Swarm

3️⃣ Test It Out!

Head over to the IPv4 address from your instance and you should see something similar to this.

After casting the vote, head to the IP address for your server and specifically head to port 5001. You’ll be brought to a webpage where you can see the percentage between cats and dogs to see which is truly man’s best friend!

Admin-level view of the results


You’ve now got a fully operational, 5-service webapp running on three different nodes! This was a joy to complete as it was the most complicated of the projects I’ve done so far.

The original lesson had me use a static plaintext password for postgress but I had recently learned how to use secrets and wanted to give it a shot! It took me a few extra tries to figure out how to get it to work, but I’m glad I took the extra time to figure it out.

This was my last Docker Swarm project for the near-future. I will be moving on to learn Kubernetes now and I’m very excited for that!

Top comments (0)

An Animated Guide to Node.js Event Loop

>> Check out this classic DEV post <<