Introduction
I still remember the first time I deployed a service on Docker Swarm. I had just set up my three-node cluster—feeling like a DevOps wizard—and was ready to deploy something meaningful. But I hit a wall. I wasn’t sure if I needed a YAML file, a docker-compose
, a custom image, or all three. Looking back, what seemed confusing at the time was actually quite straightforward—once I understood the flow.
![Deploying Your First Service on Docker Swarm]()
This article is the helping hand I wish I had back then.
We’re going to walk step-by-step through writing a Dockerfile, deploying a simple service, and then scaling it with replicas—all using plain commands and real-world examples. By the end, you’ll have deployed your own service on Swarm and scaled it like a pro.
Let’s get started with your first real Swarm deployment. You can follow this article: Setting Up Docker Swarm
Writing Dockerfiles
If Docker is the engine, then a Dockerfile is the blueprint. It tells Docker how to build your application image—what base OS to use, what files to include, and how to run it.
Let’s write a basic one together.
Imagine you’ve written a simple Python Flask app: app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Swarm!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Now you need a Dockerfile to containerize it:
# Use an official Python runtime as the base
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the current directory contents into the container
COPY . .
# Install dependencies
RUN pip install flask
# Run the app
CMD ["python", "app.py"]
That’s it! You’ve just created your own Docker image definition.
Quick Tip: Always use a slim image for production—it’s faster, smaller, and more secure.
To build your image, run:
docker build -t flask-hello-world .
![]()
You now have a reusable container image called flask-hello-world
. Let’s deploy it to your Swarm cluster.
Deploying a Simple Service
Now that you’ve built your image, it’s time to deploy it as a Swarm service.
A service in Docker Swarm is like a smart container. It’s a higher-level abstraction that comes with self-healing, automatic restarts, and built-in scaling. You don’t run containers directly on Swarm—you deploy services.
Here’s the magic command:
docker service create \
--name hello-service \
--publish 8080:5000 \
flask-hello-world
Let’s break it down:
--name hello-service
: Gives your service a name
--publish 8080:5000
: Maps Swarm’s port 8080 to your app’s internal port 5000
flask-hello-world
: The name of the image you built
![]()
Once it runs, Docker Swarm handles the rest—scheduling the container on one of your worker nodes, setting up the network, and ensuring availability.
To confirm it’s running:
docker service ls
You’ll see something like:
![]()
And to test it:
![]()
![]()
Congratulations—you’ve officially deployed your first Swarm service!
Behind the Scenes: What Just Happened?
When you ran that one-line command, Swarm did a lot:
- Pulled your image (if not present on nodes)
- Created a container based on that image
- Chose an available node to run it
- Connected it to the Swarm overlay network
- Exposed it via the Swarm routing mesh so any node can receive requests
It’s like Kubernetes, but simpler. And honestly, for small teams and projects, that simplicity is a superpower.
Scaling with Replicas
Here’s where the orchestration power really shines.
Let’s say your app goes viral (hey, it could happen!) and you need to handle more traffic. You don’t need to spin up VMs or load balancers—you just scale the service.
Try this:
docker service scale hello-service=5
Boom. Now your service is running 5 container replicas across your cluster. Swarm decides which nodes are best for running them, and distributes the load automatically.
![]()
Check status:
docker service ps hello-service
![]()
This shows which nodes are running the containers.
Want to scale down?
docker service scale hello-service=2
![]()
Swarm removes the extra replicas automatically, while ensuring zero downtime.
Anecdote: I once helped a university deploy a grading app using Swarm. During exam season, we scaled it up to 10 replicas. After the rush, we scaled it back down to 2. No redeployment, no reconfiguration. Just one line. That’s the elegance of Swarm.
Extra Tips for Scaling and Managing Services
Here are a few real-world tips I’ve picked up over the years:
Use Resource Limits
You can set CPU and memory limits per replica:
docker service create \
--name hello-service \
--limit-cpu 0.5 \
--limit-memory 256m \
--publish 8080:5000 \
flask-hello-world
Helps avoid one container hogging all your resources.
Perform Rolling Updates
If you want to update your app without downtime:
docker service update \
--image flask-hello-world:v2 \
hello-service
Swarm will roll the update out one replica at a time, so users never see a broken experience.
Monitor the Cluster
Use:
docker node ls
docker service ps hello-service
To watch what’s running where.
![]()
You can also use tools like Portainer (a web UI for Docker) for a friendly visual interface.
To stop a service running on Docker Swarm, you can use the following command:
docker service rm <service_name>
![]()
This command removes (and thus stops) the service from the Swarm cluster.
Note: This does not stop the entire Docker Swarm or other services—only the one you specify.
Conclusion
In this chapter, you turned your Swarm cluster from a quiet setup into a living, breathing, multi-node app platform.
Let’s recap:
- You wrote your first Dockerfile and built a custom image
- You deployed that image as a scalable Swarm service
- You scaled it up and down with ease
- You learned how Swarm schedules, routes, and heals your services—all with just a few commands
That’s powerful stuff.
When I first learned Swarm, this was the moment that clicked. It made container orchestration feel less like magic and more like a reliable tool I could use every day. I hope it’s doing the same for you.