DEV Community

Yash
Yash

Posted on

How to Monitor Docker Container Health and Auto-Restart on Failure

How to Monitor Docker Container Health and Auto-Restart on Failure

Your container is running but not actually working. It's accepting connections but returning 500s. Or it started but hasn't finished initializing.

Docker's built-in health checks handle all of this.

The Basic Health Check

FROM node:20-alpine

WORKDIR /app
COPY . .
RUN npm ci

# Health check: runs every 30s, fails after 3 attempts
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3   CMD curl -f http://localhost:3000/health || exit 1

CMD ["node", "server.js"]
Enter fullscreen mode Exit fullscreen mode

Or in docker-compose.yml:

services:
  app:
    image: your-app
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s  # Grace period on startup
Enter fullscreen mode Exit fullscreen mode

Check Container Health Status

# See health status
docker ps

# Detailed health info
docker inspect --format='{{json .State.Health}}' <container> | python3 -m json.tool

# Watch health checks in real time
watch -n 5 'docker inspect --format="{{.State.Health.Status}}" <container>'
Enter fullscreen mode Exit fullscreen mode

Possible statuses: starting, healthy, unhealthy

The /health Endpoint (Node.js)

// Simple health endpoint
app.get('/health', (req, res) => {
  res.status(200).json({
    status: 'ok',
    uptime: process.uptime(),
    timestamp: new Date().toISOString()
  });
});

// With dependency checks
app.get('/health', async (req, res) => {
  const checks = {};

  try {
    await db.query('SELECT 1');
    checks.database = 'ok';
  } catch {
    checks.database = 'failed';
  }

  try {
    await redis.ping();
    checks.redis = 'ok';
  } catch {
    checks.redis = 'failed';
  }

  const allOk = Object.values(checks).every(v => v === 'ok');
  res.status(allOk ? 200 : 503).json({ status: allOk ? 'ok' : 'degraded', checks });
});
Enter fullscreen mode Exit fullscreen mode

Auto-Restart on Unhealthy

services:
  app:
    image: your-app
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
Enter fullscreen mode Exit fullscreen mode

With restart: unless-stopped, Docker automatically restarts an unhealthy container.

Alert on Unhealthy Containers

#!/bin/bash
# health-monitor.sh — run via cron every minute

for container in $(docker ps --format '{{.Names}}'); do
  STATUS=$(docker inspect --format='{{.State.Health.Status}}' "$container" 2>/dev/null)
  if [ "$STATUS" = "unhealthy" ]; then
    echo "UNHEALTHY: $container at $(date)" | mail -s "Container Unhealthy: $container" you@email.com
    # Optionally restart it
    # docker restart "$container"
  fi
done
Enter fullscreen mode Exit fullscreen mode
chmod +x /usr/local/bin/health-monitor.sh
# Add to cron
* * * * * /usr/local/bin/health-monitor.sh
Enter fullscreen mode Exit fullscreen mode

I built ARIA to solve exactly this.
Try it free at step2dev.com — no credit card needed.

Top comments (0)