{"id":19760959,"url":"https://github.com/sreehariskumar/launching-a-high-availability-ip-geolocation-application-using-docker-swarm","last_synced_at":"2025-09-05T06:36:33.042Z","repository":{"id":69972255,"uuid":"604013221","full_name":"sreehariskumar/Launching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm","owner":"sreehariskumar","description":"Launch of an IP geo location application is a container cluster using docker swarm","archived":false,"fork":false,"pushed_at":"2023-03-07T06:15:17.000Z","size":19,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-28T09:54:47.879Z","etag":null,"topics":["aws-secrets-manager","container-cluster","docker","docker-swarm","ipgeolocation-api"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sreehariskumar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-20T06:30:51.000Z","updated_at":"2023-02-21T06:51:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"7c2756cd-e2cf-4fa4-b900-859db212b520","html_url":"https://github.com/sreehariskumar/Launching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sreehariskumar/Launching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreehariskumar%2FLaunching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreehariskumar%2FLaunching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreehariskumar%2FLaunching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreehariskumar%2FLaunching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sreehariskumar","download_url":"https://codeload.github.com/sreehariskumar/Launching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreehariskumar%2FLaunching-a-High-Availability-IP-Geolocation-Application-using-Docker-Swarm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273723201,"owners_count":25156302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-05T02:00:09.113Z","response_time":402,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-secrets-manager","container-cluster","docker","docker-swarm","ipgeolocation-api"],"created_at":"2024-11-12T03:39:11.367Z","updated_at":"2025-09-05T06:36:33.007Z","avatar_url":"https://github.com/sreehariskumar.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Launching a High Availability IP Geolocation Application using Docker Swarm\n\n[![Build Status](https://travis-ci.org/joemccann/dillinger.svg?branch=master)](https://travis-ci.org/joemccann/dillinger)\n\n![swarm drawio](https://user-images.githubusercontent.com/68052722/223336304-25b54a2a-3bd6-44d6-b55a-0e1fad89853f.png)\n\n\nBy utilizing the benefits of containerization, I have built an IP geolocation solution that can easily be deployed and managed, even in large and complex environments. With a focus on high availability, our application offers an unparalleled level of reliability, scalability, and performance. Let’s explore the journey of developing this application, and how Docker Swarm has helped me achieve this goal.\n\n### Introduction to Docker Swarm\n[Docker Swarm](https://docs.docker.com/engine/swarm/) is a native clustering and orchestration solution for Docker containers. It allows you to manage a group of Docker nodes as a single virtual system, making it easy to deploy and manage applications at scale. With Docker Swarm, you can create and manage a swarm of Docker nodes, and then deploy services to the swarm. Docker Swarm automatically distributes the services across the nodes in the swarm, ensuring that the services remain available even if one or more nodes fail. It also provides tools for scaling the services up or down as needed and rolling out updates to the services without downtime. Overall, Docker Swarm provides a powerful and flexible solution for managing and deploying applications in a production environment.\nYou need not have to install docker swarm separately as **Docker Swarm mode is built into the Docker Engine.**\n\nIn Docker Swarm, there are two types of nodes:\na) **Manager nodes** are responsible for controlling and coordinating the swarm. They handle tasks such as accepting service definitions, scheduling tasks, and monitoring the state of the swarm. In a multi-node swarm, there must be at least one manager node and there can be multiple manager nodes for redundancy and high availability.\n\nb) **Worker nodes** are the nodes that run the tasks and services defined in the swarm. They do not have the ability to control the swarm, and their primary function is to execute the tasks assigned to them by the manager nodes.\n\nHaving a combination of manager and worker nodes allows you to create a highly available and scalable cluster, where the manager nodes handle the orchestration of the services and the worker nodes execute the tasks. If a worker node fails, the manager nodes will automatically reschedule the tasks on another available worker node, ensuring that the services remain running and available.\n\n\n| Docker | Version |\n| ------ | ------ |\n| Client | 20.10.17 |\n| Server | 20.10.17 |\n\n### Requirements\n\n- Launch 4 instances (1 manager and 3 workers).\n- Docker must be [installed](https://www.docker.com/) and docker daemon running on all instances.\n- The user running the docker commands may be added to the docker group or else you may need sudo privilege to run the commands. (optional)\n- Create an account in [IP Geolocation API](https://ipgeolocation.io/) \u0026 copy the API key.\n- A valid domain name.\n- An ACM [certificate](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html). \n\n### Manager Node\n- Log in to the manager instance and make sure docker is installed. Change the hostname of the instance to “manager” for easy identification.\n- Run the following command to initialize the docker swarm:\n\n```s\n[ec2-user@manager ~]$ docker swarm init\n```\n```s\nSwarm initialized: current node (rhrzijigbe35akwsuqzced7ow) is now a manager.\nTo add a worker to this swarm, run the following command:\n    docker swarm join --token SWMTKN-1-3ye7nynchxc4kzcpwwhq1yk9vbvpvhbpd5qrea9nqayq0shryo-es9i2krf5fjirq2up6qf7h5ls 172.31.8.122:2377\nTo add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.\n```\n- You will receive a join token which should be executed on worked nodes for them to be added to the cluster.\n\n### Worker Node\n- Log in to each worker node and ensure that docker is installed. Change the hostname of the worker instances to worker1, worker2 \u0026 worker3 respectively.\n- Run the following command on the worker nodes to add them as worker nodes:\n\n```s\ndocker swarm join --token SWMTKN-1-3ye7nynchxc4kzcpwwhq1yk9vbvpvhbpd5qrea9nqayq0shryo-es9i2krf5fjirq2up6qf7h5ls 172.31.8.122:2377\n```\n\nOnce completed, go back to the manager node and run the following command to check whether the worker nodes have been added correctly:\n\n```s\n[ec2-user@manager ~]$ docker node ls\n```\n```s\nID                            HOSTNAME                                   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION\nrhrzijigbe35akwsuqzced7ow *   manager.ap-south-1.compute.amazonaws.com   Ready     Active         Leader           20.10.17\n51q3epwjoezb2fx24eg7oiskj     worker1.ap-south-1.compute.amazonaws.com   Ready     Active                          20.10.17\n0w4a9i725w3wln0e9qha6vvga     worker2.ap-south-1.compute.amazonaws.com   Ready     Active                          20.10.17\npdnoxuq3tha87r6cnx4cvrunr     worker3.ap-south-1.compute.amazonaws.com   Ready     Active                          20.10.17\n```\n\nBased on the node’s availability status, containers are constructed. On active nodes, new containers will be constructed. This implies that the manager node will also be used to build the containers. To prevent this, the management node’s status must be changed to [Drain](https://docs.docker.com/engine/swarm/swarm-tutorial/drain-node/), which stops it from receiving new tasks.\n\n\n### Changing the Availability Status of the Manager Node to Drain\n\n```s\ndocker node update --availability drain manager.ap-south-1.compute.amazonaws.com\n```\n```s\ndocker node ls\n```\n```s\nID                            HOSTNAME                                   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION\nrhrzijigbe35akwsuqzced7ow *   manager.ap-south-1.compute.amazonaws.com   Ready     Drain          Leader           20.10.17\n51q3epwjoezb2fx24eg7oiskj     worker1.ap-south-1.compute.amazonaws.com   Ready     Active                          20.10.17\n0w4a9i725w3wln0e9qha6vvga     worker2.ap-south-1.compute.amazonaws.com   Ready     Active                          20.10.17\npdnoxuq3tha87r6cnx4cvrunr     worker3.ap-south-1.compute.amazonaws.com   Ready     Active                          20.10.17\n```\nAs you can see that the availability status of the manager node has been changed to **“Drain”**.\n\n### Adding Node Labels\n- In this project, we will be running the api containers and the frontend containers in worker1 and worker2 only.\n- The worker3 is solely used for running a redis container for caching.\n- We can use labels to ensure that certain containers are only placed on worker nodes that meet specific requirements. We can use labels to ensure that certain containers are only placed on worker nodes that meet specific requirements.\n\nWe will be using the **“service=api-service”** label for worker1 \u0026 worker2. And the **“service=redis-service”** label for worker3.\n\nRemember: **docker node update** only accepts exactly 1 argument. So, each label has to be added individually.\n```s\ndocker node update --label-add service=api-service worker1.ap-south-1.compute.amazonaws.com\n\n```\n```s\ndocker node update --label-add service=api-service worker2.ap-south-1.compute.amazonaws.com\n```\n```s\ndocker node update --label-add service=redis-service worker3.ap-south-1.compute.amazonaws.com\n```\n\nTo check for the label of a node.\n\n```s\ndocker node inspect worker1.ap-south-1.compute.amazonaws.com\n\n\"Labels\": {\n    \"service\": \"api-service\"\n},\n```\nSimilarly, check the label has been added for all the worker nodes.\n\n### Creating an Overlay Network\nAn overlay network in Docker Swarm is a virtual network that enables containers running on different worker nodes to communicate with each other as if they were all connected to the same network. An overlay network is created and managed by Docker Swarm and provides a way to securely connect containers in the swarm, regardless of the worker nodes they are running on.\n\nThe purpose of an overlay network in Docker Swarm is to provide a networking solution for applications running in the swarm. Without an overlay network, containers running on different worker nodes would not be able to communicate with each other, making it difficult to build and run distributed applications. By creating an overlay network, you can easily connect containers running on different worker nodes, allowing them to communicate and work together to provide a seamless experience for your users.\n\n```s\ndocker network create --driver overlay geo-net\n```\n```s\ndocker network ls\n\nNETWORK ID     NAME              DRIVER    SCOPE\n0ff8bddf838c   bridge            bridge    local\nc5ae20a136fc   docker_gwbridge   bridge    local\nlfu0cl07jgx2   geo-net           overlay   swarm     \u003c==\nb7e2aefe7503   host              host      local\ndmb9ti5i1frs   ingress           overlay   swarm\n411f646cc1d8   none              null      local\n```\n\n### Creating Redis Service\nRedis container is used as a caching service for our application.\n\nHere, **only 1** redis container is created in a single instance.\nImagine if multiple redis containers were being used for caching and, an api container receives a request, it first connects to the redis container to see if the requested data is present there. If not, the api container then contacts with the api service provider, and the requested data is then cached in the redis container and served.\n\nIf a new request for the same IP address is received on the api container and this time the request is being forwarded to another redis container it may not have the cached data. Here, the api container repeats the process, and this time, caching is done for the same IP address on the new redis container. In order to prevent this, only one redis container is utilised.\n\n\n```s\ndocker service create --name geo-redis --constraint node.labels.service==redis-service --network geo-net redis:latest\n\ny226j4sulmlcbngghatcbpigi\noverall progress: 1 out of 1 tasks \n1/1: running   [==================================================\u003e] \nverify: Service converged \n```\n\n#### Explanation:\n- This command creates a Docker service called “geo-redis” using the latest version of the Redis image.\n- **--constraints** are condition which specifies that the service will only run on nodes with the label **“service”** set to **“redis-service”**, which is worker3.\n- The service is also connected to the **“geo-net”** network.\n\nTo list the created service:\n```s\ndocker service ls\n\nID             NAME        MODE         REPLICAS   IMAGE          PORTS\ny226j4sulmlc   geo-redis   replicated   1/1        redis:latest\n```\n\nTo list the nodes that are associated with the service:\n\n```s\ndocker service ps geo-redis\n\nID             NAME          IMAGE          NODE                                       DESIRED STATE   CURRENT STATE            ERROR     PORTS\n9tpotiex5e49   geo-redis.1   redis:latest   worker3.ap-south-1.compute.amazonaws.com   Running         Running 47 seconds ago\n```\n\n### Creating API Services\n\n```s\ndocker service create --name geo-api -p 8081:8080 --constraint node.labels.service==api-service --replicas 4 --network geo-net -e REDIS_PORT=\"6379\" -e REDIS_HOST=\"geo-redis\" -e APP_PORT=\"8080\" -e API_KEY_FROM_SECRETSMANAGER=\"True\" -e SECRET_NAME=\"xxxxx\" -e SECRET_KEY=\"xxxxx\" -e REGION_NAME=\"xxxxx\" sreehariskumar/ip-geo-location-finder\n```\n\n#### Explanation:\n- This command creates a Docker service called **“geo-api”** using the image **“sreehariskumar/ip-geo-location-finder:latest”**.\n- The service maps the host’s port **8081** to the container’s port 8080.\n- The service will only run on nodes with the label **“service”** set to **“api-service”**.\n- The number of **replicas** of this service is 4.\n- The service is connected to the **“geo-net”** network.\n\n The following environment variables are passed to the service:\n - **REDIS_PORT** is set to “6379”\n - **REDIS_HOST** is set to “geo-redis”.\n Here, the name of the redis service is mentioned for the api service to communicate with the redis service.\n - **APP_PORT** is set to “8080”.\n - **API_KEY_FROM_SECRETSMANAGER** is set to “True”, which defines the API key that should be fetched from our stored secret.\n - **SECRET_NAME** defines the name of our secret.\n - **SECRET_KEY** is key to identifying our secret.\n - **REGION_NAME** is the region of our secret.\n \nListing the nodes that are associate with the service:\n```s\ndocker service ps geo-api\n\nID             NAME        IMAGE                                          NODE                                       DESIRED STATE   CURRENT STATE           ERROR     PORTS\nxagt0bapjjzh   geo-api.1   sreehariskumar/ip-geo-location-finder:latest   worker2.ap-south-1.compute.amazonaws.com   Running         Running 3 minutes ago             \nz5xhhgen194o   geo-api.2   sreehariskumar/ip-geo-location-finder:latest   worker1.ap-south-1.compute.amazonaws.com   Running         Running 3 minutes ago             \n0xgna3wf4jll   geo-api.3   sreehariskumar/ip-geo-location-finder:latest   worker2.ap-south-1.compute.amazonaws.com   Running         Running 3 minutes ago             \nzfmf2n49iocm   geo-api.4   sreehariskumar/ip-geo-location-finder:latest   worker1.ap-south-1.compute.amazonaws.com   Running         Running 3 minutes ago\n```\nAs you can see the replicas have been created across worker1 and worker2.\n\n### Creating Frontend Service\nFronend is just a container that fetches the details of the provided IP address from the api containers and displays it in a readable HTML table format.\n\n```s\ndocker service create --name geo-frontend -p 8082:8080 --constraint node.labels.service==api-service --replicas 4 --network geo-net -e API_SERVER=\"geo-api\" -e API_SERVER_PORT=\"8080\" -e APP_PORT=\"8080\" sreehariskumar/ipgeolocation-frontend:latest\n```\n\n#### Explanation:\n- This command creates a Docker service called **“geo-frontend”** using the image **“sreehariskumar/ipgeolocation-frontend:latest”**.\n- The service maps the host’s port **8082** to the container’s port 8080.\n- The service will only run on nodes with the label **“service”** set to **“api-service”**.\n- The number of **replicas** of this service is 4.\n- The service is connected to the **“geo-net”** network.\n\nThe following environment variables are passed to the service:\n\n- **API_SERVER** is set to “geo-api”.\nHere, the name of the api service is mentioned for the frontend service to communicate with the api service.\n- **API_SERVER_PORT** is set to “8080”, which defines the api containers are running on port 8080.\n- **APP_PORT** is set to “8080”, which specifies the port of the frontend app.\n\nListing the nodes that are associate with the service:\n```s\ndocker service ps geo-frontend\n\nID             NAME             IMAGE                                       NODE                                       DESIRED STATE   CURRENT STATE                ERROR     PORTS\nxhzkx8j1t4za   geo-frontend.1   sreehariskumar/ipgeolocation-frontend:latest   worker2.ap-south-1.compute.amazonaws.com   Running         Running about a minute ago             \nctcdzz8w7ivp   geo-frontend.2   sreehariskumar/ipgeolocation-frontend:latest   worker1.ap-south-1.compute.amazonaws.com   Running         Running about a minute ago             \ng7s77stsdkvq   geo-frontend.3   sreehariskumar/ipgeolocation-frontend:latest   worker2.ap-south-1.compute.amazonaws.com   Running         Running about a minute ago             \nvar3d0srtsci   geo-frontend.4   sreehariskumar/ipgeolocation-frontend:latest   worker1.ap-south-1.compute.amazonaws.com   Running         Running about a minute ago       \n```\nAs you can see the replicas have been created across worker1 and worker2.\n\n### Load Balancing the Instances\nAn **nginx** container or an **Application Load Balancer** can be used to balance the traffic here. We’ve used an nginx container previously in an article. This time, we will be using an Application Load Balancer.\n\n### Redirecting HTTP to HTTPS\nWe will configure the HTTP requests received on the load balancer to redirect to HTTPS.\nFor this, we need to add a new listener port on the load balancer.\n\n### Creating Records in Route53\nWe need to create two records in the hosted zone to publicly access the api targets and the frontend targets.\n\n\n**I hope this project was helpful to you.\nPlease reach out to me in case of any queries also please share your reviews.**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsreehariskumar%2Flaunching-a-high-availability-ip-geolocation-application-using-docker-swarm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsreehariskumar%2Flaunching-a-high-availability-ip-geolocation-application-using-docker-swarm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsreehariskumar%2Flaunching-a-high-availability-ip-geolocation-application-using-docker-swarm/lists"}