Zero-Downtime Deployments with Docker Swarm and Portainer - Part 2/2
Zero-downtime deployments with Docker Swarm and Portainer Part 2/2 What have we achieved so far? …

Before we dive into the details, let’s clarify what Zero-downtime deployments are. Zero-downtime deployments are deployments that have no downtime. This means that the application being deployed is not offline during the deployment. This is especially important for applications that need to run 24/7. The high availability of applications is becoming increasingly important. Let’s be honest, who wants to wait when Netflix and others update their applications?
Both approaches have the same goal, but there are significant differences. Therefore, let’s take a look at both approaches using a table.
| Operation | New versions are gradually introduced into production by updating individual instances step by step. |
| Time Intervals | The update requires some time as it is performed step by step on individual instances. |
| Downtime | Short downtimes are possible as each step involves stopping an instance and replacing it with the new version. |
| Versioning | During the update, different versions of the application may run in parallel for a short time. |
| Operation | Zero Downtime Deployments allow a new version of the application to be introduced into production without any downtime for users. |
| Time Intervals | Zero Downtime Deployments aim for a seamless update without time delays or operational interruptions. |
| Downtime | The main difference from Rolling Updates is that Zero Downtime Deployments have no downtime. The application remains continuously available even during the update. |
| Versioning | In Zero Downtime Deployments, new versions of the application are gradually brought into production, and only when the new version is deemed fully functional and stable is the old version shut down. |
Enough theory. How do I now implement a Zero-downtime deployment with Docker Swarm and Portainer?
The following prerequisites are required:
docker-stack.yaml)Since I have already shown in the article Why Portainer how to deploy a basic YAML file via Portainer, I will not go into further detail here.
The focus is much more on the commands that Docker offers me to achieve a Zero-downtime deployment. In Part 2, the focus will be more on the connection between Portainer and the repository.
Let’s start with the YAML file. It looks like this:
version: '3.8'
services:
db:
image: mariadb:10.6.4-focal
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
image: wordpress:latest
volumes:
- wp_data:/var/www/html
ports:
- 7002:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
wp_data:
So far, nothing special. We have a WordPress instance with a database. If a new version of WordPress is released, the application must go offline to roll out the new version. This is, of course, not optimal.
The next step is therefore to integrate a Docker Healthcheck that checks whether an application is running correctly. It would theoretically also work without a Healthcheck, but there are containers that are still displayed as running even when they are no longer running internally.
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # Simply tests if the application is accessible via port 80
interval: 30s
timeout: 10s
retries: 5
After this, we can check in Portainer whether our application is healthy.

That already looks very good.
I will not go into further detail about the Healthcheck here. If you want to know more, feel free to read the Docker Manuals.
Now that we have the Healthcheck, we can turn to the actual Zero-downtime deployment. For this, we need to extend our YAML file by a few lines.
deploy:
replicas: 2 # Number of instances that should run simultaneously
update_config: # The configuration for the update
order: start-first # The order in which the instances should be updated
failure_action: rollback # What should happen if an update fails
rollback_config: # The configuration for the rollback
parallelism: 1 # How many instances should be rolled back simultaneously
order: start-first # The order in which the instances should be rolled back
restart_policy: # The configuration for the restart
condition: on-failure # Under what conditions a restart should be performed
Now we have everything we need to perform a Zero-downtime deployment. You can find the complete stack here
Why do we run two instances simultaneously?
Simply put, if we only run one instance and that instance fails, we no longer have an instance providing the application. That’s why we run two instances simultaneously. If one instance fails, we still have a second instance providing the application. In a Swarm cluster, Docker can also distribute the Container across multiple nodes.
This way, we can achieve high availability of the application.
If we now want to update our WordPress instance, we can easily do so via Portainer. However, I will show you this in Part 2 of this post, as it would exceed the scope here.
Sources:
Zero-downtime deployments with Docker Swarm and Portainer Part 2/2 What have we achieved so far? …
Five Key Features of Portainer 1. Docker Environments 2. Access Control 3. CI/CD Capabilities 4. …
Why This Post? What is Portainer? Practical Section Deploying Portainer Setting Up Portainer …