# Docker Health Check Patterns

Quick reference for adding health checks to Docker containers.

## Basic: curl (requires curl in image)

```dockerfile
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
```

## Better: wget (available in Alpine)

```dockerfile
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
```

## Best for Node.js: native HTTP check (no extra binaries)

```dockerfile
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
  CMD node -e "require('http').get('http://localhost:3000/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) }).on('error', () => process.exit(1))"
```

Works in `node:slim` and `node:alpine` without installing curl or wget.

## Production: dedicated script with dependency checks

```bash
#!/bin/sh
# healthcheck.sh

wget -q --spider http://localhost:3000/health || exit 1

if ! pg_isready -h localhost -p 5432 > /dev/null 2>&1; then
  exit 1
fi

if [ -n "$REDIS_URL" ]; then
  redis-cli -u "$REDIS_URL" ping > /dev/null 2>&1 || exit 1
fi

exit 0
```

## Key parameters

| Parameter | Default | Recommendation |
|-----------|---------|----------------|
| `--interval` | 30s | 30s for most apps |
| `--timeout` | 30s | 5-10s (fail fast) |
| `--start-period` | 0s | **Set this!** 30-60s for apps that need warmup |
| `--retries` | 3 | 3 is fine |

## Common mistakes

- **Forgetting `--start-period`** — container gets killed during startup
- **Using `curl` in slim images** — use wget or Node.js native instead
- **Not checking dependencies** — app is "healthy" but database is down
- **Too short timeout** — intermittent failures cause unnecessary restarts
