← Back to DevBytes

Docker Restart Policies: Best Practices and Common Pitfalls

Introduction to Docker Restart Policies

Docker restart policies control whether containers should be automatically restarted when they exit, and under what conditions. They are essential for building resilient, self-healing containerized applications, but misusing them can lead to unexpected behaviour, disk exhaustion, or infinite crash loops.

What Are Docker Restart Policies?

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

A restart policy is a configuration option that tells the Docker daemon what to do when a container’s main process terminates. By default, Docker does not restart a stopped container. You can override this by setting one of the available policies at container creation or via orchestration tools like Docker Compose or Swarm.

Available Policies

Why Restart Policies Matter

In production, services must be highly available. Restart policies help achieve that without external process supervisors like systemd or supervisord inside the container. They enable quick recovery from transient failures, crashes due to resource limits, or intermittent network glitches. However, they can mask deeper issues: a container crashing repeatedly may go unnoticed, causing log spam, resource contention, or cascading failures. Understanding the trade-offs is critical before applying a policy blindly.

How to Apply a Restart Policy

You can set the restart policy at container creation via docker run, in a Docker Compose file, or in Docker Swarm services. Here are practical examples for each context.

Using docker run

# No automatic restart (default)
docker run -d --name my-app nginx

# Always restart
docker run -d --restart always --name my-app nginx

# Restart only on non-zero exit, up to 5 attempts
docker run -d --restart on-failure:5 --name my-app nginx

# Restart unless manually stopped
docker run -d --restart unless-stopped --name my-app nginx

Using Docker Compose

In a docker-compose.yml file, the restart policy is defined per service under the restart key. This is the simplest way to embed the policy alongside your application definition.

version: '3.8'
services:
  web:
    image: nginx:alpine
    restart: always
    ports:
      - "80:80"

  worker:
    image: my-worker:latest
    restart: on-failure:5
    environment:
      - QUEUE=default

For Swarm mode services, the syntax changes slightly (see the advanced section below).

Best Practices

Common Pitfalls

Infinite Crash Loops

With always or unless-stopped, a container that crashes immediately (non‑zero exit) is restarted endlessly. Docker applies an exponential back‑off delay between restarts (starting at 100 ms, doubling up to 1 min), but even with this back‑off, a persistent crash can still flood logs and consume CPU. Always set a max‑retry limit (on-failure:5) or implement external circuit‑breakers. Combine with health checks so that a container stuck in a crash loop eventually gets marked unhealthy.

Disk Space Exhaustion from Logs

Every restart writes new log entries. Without log rotation, a crash‑looping container can fill the host disk in hours. Always pair restart policies with logging drivers that enforce size limits, or use Docker’s built‑in log options:

docker run -d --restart always --log-opt max-size=10m --log-opt max-file=3 my-app

Orphaned Containers After Manual Stop

Using always on a container you later want to permanently stop creates a surprise: after a Docker daemon restart (e.g., host reboot), the container comes back to life. To truly stop it you must also remove the container or change its restart policy. unless-stopped avoids this — it remembers the manual stop state across daemon restarts.

Conflicting with Orchestration Restarts

In Docker Swarm or Kubernetes, the higher‑level orchestrator manages restarts. For Swarm services, always use deploy.restart_policy instead of the container‑level --restart flag. Mixing the two can lead to conflicting restart behaviours and make troubleshooting difficult.

Ignoring Exit Code Semantics

on-failure only restarts on non‑zero exit codes. If your application catches fatal signals and exits with code 0, Docker will treat that as a “successful” termination and won’t restart it. Ensure your app exits with a non‑zero code on unexpected termination, or use always / unless-stopped when exit‑code semantics are unreliable.

Restart Policies on Data‑Initialization Containers

For containers that run database migrations or seed data, using always causes repeated initialization, potentially corrupting data or causing duplicate entries. Use on-failure:0 (no retries) or simply omit the restart policy to ensure they run once and stop.

Advanced: Restart Policy in Docker Swarm

Swarm mode offers a more granular restart policy under the deploy key. It supports condition types, delay, maximum attempts, and a failure evaluation window.

version: '3.8'
services:
  api:
    image: my-api:stable
    deploy:
      restart_policy:
        condition: any               # 'none', 'on-failure', or 'any'
        delay: 5s                    # Wait before restart attempt
        max_attempts: 3              # Give up after 3 failures
        window: 120s                 # Time window to evaluate failure

The condition: any behaves like always, while on-failure respects non‑zero exits. The window parameter defines how long Docker waits after a successful start before resetting the failure counter, preventing a flapping service from being prematurely declared healthy. This provides fine‑grained control that basic container‑level policies lack.

Monitoring and Debugging Restarts

To check the current restart policy and the number of times a container has been restarted:

# Restart count
docker inspect --format '{{.RestartCount}}' my-app

# Active restart policy
docker inspect --format '{{.State.RestartPolicy}}' my-app

High restart counts indicate instability. Integrate these metrics into your monitoring stack (Prometheus, Datadog, etc.) and set alerts. Also, centralize container logs to quickly identify crash patterns.

Conclusion

Docker restart policies are a lightweight yet powerful mechanism for keeping services alive. By choosing the appropriate policy, setting sensible retry limits, combining them with health checks and log management, you can build robust, self‑healing containerized systems. However, blindly enabling always without understanding failure modes can turn a minor crash into a major outage. Always test your assumptions, monitor restart counts, and align restart behaviour with both your application’s architecture and your deployment orchestration layer. When used correctly, restart policies form the foundation of resilient container operations.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles