Request change

How to Achieve Zero-Downtime in Docker

Mastering Seamless Updates: Why ZeroDowntime Docker Compose Deployments with dockerrollout Are a MustKnowIn the world of application deployment, nothing disrupts user experience quite like downtime. Imagine your website or service going offline, even for a brief moment, every time you push an...

How to Achieve Zero-Downtime in Docker

Mastering Seamless Updates: Why Zero-Downtime Docker Compose Deployments with docker-rollout Are a Must-Know

In the world of application deployment, nothing disrupts user experience quite like downtime. Imagine your website or service going offline, even for a brief moment, every time you push an update. For many developers and system administrators running applications with Docker Compose, this has been a frustrating reality. But what if there was a simple, elegant way to update your services without a single second of interruption? Enter docker-rollout, a powerful tool that makes zero-downtime Docker Compose deployments a reality.

The Pain Point: Why Docker Compose Causes Downtime

Historically, deploying new versions of applications managed by Docker Compose presented a significant challenge. When you update a container using standard docker-compose commands, the existing container is stopped before the new one is started. This sequential process inevitably leads to a period of downtime, which can range from 10-20 seconds or even longer, depending on your application’s boot time. For applications that need to be continuously available, this brief interruption is unacceptable.

While robust container orchestration tools like Docker Swarm or Kubernetes offer native zero-downtime deployment capabilities, they can often be overkill for single-server Docker Compose setups. Learning and managing the complexities of these full-fledged clusters might introduce more overhead than necessary for a project that doesn’t require multi-node scalability.

The Game-Changer: docker-rollout

This is where docker-rollout shines. It’s a Docker CLI plugin designed specifically for zero-downtime deployments with Docker Compose. Instead of resorting to complex orchestration systems or writing elaborate shell scripts, docker-rollout provides a straightforward, single-command solution.

How it works is elegantly simple: When you initiate a docker rollout <service> command, it doesn’t immediately stop your running container. Instead, it takes the following steps:

  1. Scales Up: docker-rollout temporarily scales your service to two instances, meaning the new version of your container starts alongside the old one.
  2. Health Check & Readiness: It then waits until the new service instance is healthy. This is where your service’s healthcheck definition in your docker-compose.yml becomes critically important.
  3. Proxy Update: Once the new container is confirmed healthy, it instructs your proxy server (like Traefik or NGINX) to route all incoming traffic to the newly deployed, healthy service.
  4. Old Container Shutdown: Finally, the old container is gracefully stopped.

This intelligent sequence ensures that your application remains available and responsive throughout the deployment process, eliminating the dreaded downtime.

Why Everyone Should Learn and Understand docker-rollout

Understanding docker-rollout is crucial for anyone managing Docker Compose-based applications, for several compelling reasons:

  • Eliminates Downtime for Users: This is the most direct and impactful benefit. By ensuring continuous availability, docker-rollout significantly improves the user experience for your applications. No more broken user sessions or frustrated visitors during updates.
  • Simplicity vs. Complexity: For single-server deployments, docker-rollout offers a much simpler alternative to full-blown container orchestration tools like Kubernetes or Docker Swarm. While Swarm is built-in and compatible with Compose, it has certain limitations for single-node use cases, such as challenges with one-off tasks like database migrations and unsupported Compose parameters. docker-rollout lets you “keep it super simple” (KISS) while still achieving a key orchestration benefit.
  • Boosts Deployment Confidence: Knowing that your deployments won’t cause outages allows for more frequent and less stressful updates. This fosters a more agile development cycle and reduces the risk associated with pushing new features or bug fixes.
  • Leverages Existing Docker Compose Skills: You don’t need to learn an entirely new ecosystem. docker-rollout integrates seamlessly with your existing Docker Compose files and workflow, acting as a drop-in replacement for the standard docker compose up -d <service> command.
  • Essential for Robust Single-Node Setups: If you’re hosting web services on a home server or for friends and family, where downtime during updates is problematic but full orchestration is overkill, docker-rollout is the perfect sweet spot. It provides a more robust deployment strategy for these scenarios without significant additional complexity or dependencies.
  • Supports Advanced Deployment Patterns (Container Draining): Beyond basic zero-downtime, docker-rollout also facilitates container draining. This advanced feature ensures that currently processed requests are not dropped when the old container is stopped. By adding a specific health check and a pre-stop-hook, you can mark an old container as unhealthy, allowing your proxy to stop sending new requests to it before it’s removed, ensuring truly seamless transitions.
Getting Started: The Practical Steps

To implement zero-downtime deployments with docker-rollout, you’ll need a few key components:

Install docker-rollout: It’s a straightforward installation process, requiring you to create a directory for Docker CLI plugins, download the script, and make it executable:

# Create directory for Docker cli plugins
mkdir -p ~/.docker/cli-plugins

# Download docker-rollout script to Docker cli plugins directory
curl https://raw.githubusercontent.com/wowu/docker-rollout/main/docker-rollout -o ~/.docker/cli-plugins/docker-rollout

# Make the script executable
chmod +x ~/.docker/cli-plugins/docker-rollout

Check docker rollout Help

docker rollout

Create a Flask APP

mkdir flask_app/app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello from Flask!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Create A simple Dockerfile for Flask APP

FROM python:3.9-alpine
WORKDIR /app
COPY app.py .
RUN pip install flask
EXPOSE 5000
CMD &#91;"python", "app.py"]

Implement a Proxy Server: A proxy like NGINX or Traefik is essential to route traffic to the correct containers. Traefik is often a popular choice due to its dynamic configuration capabilities with Docker. You’ll set up a docker-compose.yaml file to run your proxy, binding port 80 to it:

vi docker-compose.yaml
version: "3.9"
services:
  nginx:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.entrypoints=web"
      - "traefik.http.routers.nginx.rule=Host(`nginx.localhost`)"
    healthcheck:
      test: &#91;"CMD", "wget", "-q", "--spider", "http://localhost"]
      interval: 5s
      timeout: 2s
      retries: 3

  apache:
    image: httpd:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.apache.entrypoints=web"
      - "traefik.http.routers.apache.rule=Host(`apache.localhost`)"
    healthcheck:
      test: &#91;"CMD", "wget", "-q", "--spider", "http://localhost"]
      interval: 5s
      timeout: 2s
      retries: 3

  flask:
    build: ./flask_app
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.flask.entrypoints=web"
      - "traefik.http.routers.flask.rule=Host(`flask.localhost`)"
    healthcheck:
      test: &#91;"CMD", "curl", "-f", "http://localhost:5000/"]
      interval: 5s
      timeout: 2s
      retries: 3

Start Traefik and the Apps

docker-compose up -d

Lets check Running containers

docker ps

In my case Flask App is unhealthy, if i try rollout it will not do rollout since our container had unhealthy status

docker rollout flask

I will rollout nginx image now

docker rollout nginx

Lets add Dockerfile fix to Flask App make app healthy and do rollout

vi Dockerfile

``` FROM python:3.9-alpine WORKDIR /app COPY app.py . RUN pip install flask RUN apk add –no-cache curl #

Share
Helpful?

Request a change or update

Suggest a correction or content update. The post author or an admin will be notified and can resolve or respond.

Comments (0)

No comments yet. Be the first to share your thoughts.

Leave a comment