Docker Health Checks: Building Self-Healing Containers
Implement effective health checks in Docker and Podman containers. Learn start_period, interval, timeout, retries, and integration with orchestration tools.
Docker health checks let containers report their status automatically. When a container becomes unhealthy, Docker can restart it, notify monitoring systems, or remove it from load balancers.
Why Health Checks Matter
Without health checks:
- Container running but app crashed
- Database accepting connections but can't execute queries
- Web server up but returning 500 errors
- Manual intervention required
With health checks:
- Automatic failure detection
- Self-healing (auto-restart)
- Load balancer integration
- Monitoring alerts
Basic Health Check
Simple HTTP Check
# Dockerfile
FROM nginx:latest
# Add health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD curl -f http://localhost/ || exit 1
Or in compose:
# docker-compose.yml
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Health Check Fields
test— Command to run (exit 0 = healthy, 1 = unhealthy)interval— Time between checks (default: 30s)timeout— Max time for check (default: 30s)retries— Failed checks before unhealthy (default: 3)start_period— Grace period for startup (default: 0s)
Common Health Check Patterns
Pattern 1: HTTP Endpoint
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
Application should return 200 OK when healthy:
// Node.js example
app.get('/health', (req, res) => {
// Check dependencies
if (db.connected && cache.connected) {
res.status(200).json({ status: 'healthy' });
} else {
res.status(503).json({ status: 'unhealthy' });
}
});
Pattern 2: Database Connection
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
Pattern 3: Process Check
healthcheck:
test: ["CMD-SHELL", "pidof nginx || exit 1"]
interval: 30s
timeout: 5s
retries: 3
Pattern 4: Custom Script
healthcheck:
test: ["CMD", "/app/healthcheck.sh"]
interval: 30s
timeout: 10s
retries: 3
#!/bin/bash
# /app/healthcheck.sh
# Check database
if ! pg_isready -h db -U postgres; then
echo "Database not ready"
exit 1
fi
# Check cache
if ! redis-cli -h cache ping | grep -q PONG; then
echo "Cache not ready"
exit 1
fi
# Check disk space
if [ $(df /data | tail -1 | awk '{print $5}' | sed 's/%//') -gt 90 ]; then
echo "Disk space low"
exit 1
fi
echo "All checks passed"
exit 0
Advanced Health Checks
Multi-Stage Health Check
healthcheck:
test: |
bash -c '
# Check if process is running
pidof node || exit 1
# Check HTTP endpoint
curl -f http://localhost:3000/health || exit 1
# Check database connection
node -e "require('./db').check().then(() => process.exit(0)).catch(() => process.exit(1))"
'
interval: 30s
timeout: 15s
retries: 3
Gradual Health Check
healthcheck:
test: |
bash -c '
# First 5 minutes: just check process
if [ $$(ps -p 1 -o etimes=) -lt 300 ]; then
pidof node || exit 1
else
# After 5 minutes: full health check
curl -f http://localhost:3000/health || exit 1
fi
'
interval: 10s
timeout: 5s
retries: 5
start_period: 60s
Using Health Checks
View Health Status
# Check container health
docker ps
# Shows (healthy), (unhealthy), or (health: starting)
# Detailed health info
docker inspect --format='{{.State.Health.Status}}' container_name
# View health check logs
docker inspect --format='{{json .State.Health}}' container_name | jq
Auto-Restart Unhealthy Containers
services:
web:
image: myapp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
retries: 3
restart: on-failure
Load Balancer Integration
Nginx upstream with health checks:
upstream backend {
server backend1:8080;
server backend2:8080;
# Requires nginx plus
health_check interval=5s fails=3 passes=2;
}
HAProxy with health checks:
backend app
balance roundrobin
option httpchk GET /health
server app1 app1:8080 check inter 5s fall 3 rise 2
server app2 app2:8080 check inter 5s fall 3 rise 2
Docker Compose with Health Checks
Complete Example
version: '3.8'
services:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
web:
image: myapp:latest
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
ports:
- "80:3000"
volumes:
pgdata:
The depends_on with condition: service_healthy ensures web starts only after db and cache are healthy.
Monitoring Health Checks
Prometheus Metrics
services:
web:
image: myapp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
labels:
- "prometheus-job=myapp"
Alerting
# docker-compose.yml
services:
web:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
restart: on-failure
logging:
driver: syslog
options:
syslog-address: "tcp://logs.example.com:514"
FoxTerm Health Check Support
FoxTerm makes health checks visual and manageable:
Health Dashboard
- Real-time health status for all containers
- Health check history and trends
- Failure notifications
- Quick restart actions
Health Check Editor
- Visual health check configuration
- Test health checks before deploying
- Template library for common patterns
- Validation and best practices
Integration
- Auto-detect health check status
- Alert on unhealthy containers
- One-click restart
- Health check logs viewer
Best Practices
- Implement health endpoints —
/healthshould check all dependencies - Set appropriate intervals — Don't check too frequently (overhead) or too slowly (delayed detection)
- Use start_period — Give apps time to initialize
- Check dependencies — Health check should verify database, cache, etc.
- Log health check results — Debug failures easily
- Test health checks — Verify they work before production
- Monitor trends — Track health check failures over time
Conclusion
Docker health checks enable self-healing containers that detect and recover from failures automatically. Combined with proper restart policies and monitoring, they significantly improve application reliability.
FoxTerm makes health checks visual and manageable, with real-time status and one-click actions.
FoxTerm Pro includes health check monitoring and management. Download at foxterm.app.