Docker Container Healthchecks
What this article covers
- What a healthcheck is.
- How to define healthchecks in Dockerfiles and Compose.
- How Docker responds to failures.
- Practical examples for web services, databases, and Ollama.
- Tips and common pitfalls.
Introduction: Docker container healthchecks
A Docker container can be running without the application inside it actually being ready or functional. Healthchecks help verify an application’s state on a regular basis. Docker marks a container as healthy or unhealthy and can automatically restart it or trigger alerts when needed.
This article explains how healthchecks work and how to set them up for typical AI services like Ollama, Open WebUI, or databases.
Key concepts
- Healthcheck: Regular verification of application health.
- Interval: Time between checks.
- Timeout: Maximum wait time for a check result.
- Start Period: Time during which failures are ignored to allow startup.
- Retries: Number of allowed failures before a container becomes
unhealthy. - Restart Policy: Behavior when restarting.
- Exit Code: Return value of the healthcheck command. 0 means healthy, 1 means unhealthy.
Why healthchecks matter
- Containers are only marked as ready when the application is actually running.
- Issues are detected early.
- Reverse proxies and load balancers can prefer healthy containers.
- Automatic restarts increase availability.
- Monitoring can react to health status.
Healthcheck in Dockerfile
FROM nginx:latest
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/ || exit 1
This healthcheck verifies every 30 seconds that the local web server responds.
Healthcheck in Docker Compose
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
restart: unless-stopped
Checking status
docker ps
The STATUS column shows (healthy) or (unhealthy).
For details:
docker inspect --format='{{.State.Health.Status}}' containername
Example: Ollama
services:
ollama:
image: ollama/ollama
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:11434/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
volumes:
- ollama-data:/root/.ollama
restart: unless-stopped
This healthcheck verifies that the Ollama API is reachable.
Example: Open WebUI
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 60s
restart: unless-stopped
Example: PostgreSQL
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: appdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d appdb"]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
restart: unless-stopped
More complex checks
Sometimes a simple HTTP status isn’t enough. You can use custom scripts to verify that critical functionality works:
#!/bin/sh
if curl -f http://localhost/api/health | grep -q '"ok":true'; then
exit 0
else
exit 1
fi
Place this in the container and invoke it as a healthcheck.
Restart policies
| Policy | Behavior |
|---|---|
| no | Never restart. |
| on-failure | Restart only on error code. |
| always | Always restart. |
| unless-stopped | Restart unless manually stopped. |
Recommended combination:
restart: unless-stopped
Disabling healthchecks
If a prebuilt image has an unsuitable healthcheck, you can override it:
services:
app:
image: some-image
healthcheck:
disable: true
Tips
- Use a meaningful endpoint for healthchecks, not just process presence.
- Set the start period generously.
- Don’t make the interval too short to avoid wasting resources.
- Adjust timeout to match actual response times.
- Monitor healthcheck logs.
- Keep custom healthcheck scripts short.
Common pitfalls
- Interval too aggressive: High load from constant checks.
- Start period too short: Container marked unhealthy during startup.
- Wrong protocol: Checking HTTPS when only HTTP is running.
- Missing tools in image:
curlnot present, script fails. - Only checking process: Application is hung but process still runs.
- No restart policy: Unhealthy containers keep running.
- Healthcheck output in logs: Confusing log entries.
Further reading
- BotServ.de Docker Monitoring
- BotServ.de Docker Logs
- BotServ.de Docker Security
- BotServ.de Docker Compose
FAQ: Docker healthchecks
Does every container need a healthcheck? No, but it’s recommended for critical services.
How often does a healthcheck run? By default every 30 seconds, but this is configurable.
What happens when unhealthy?
Docker displays the status. With a restart policy, the container can be restarted automatically.
Can I use custom commands? Yes, any shell or CMD-based check is possible.
Are healthchecks the same as readiness probes in Kubernetes? Similar, but Kubernetes also offers readiness and startup probes.
Sources and further reading
- Docker Healthcheck: https://docs.docker.com/engine/reference/builder/#healthcheck
- Docker Restart Policy: https://docs.docker.com/config/containers/start-containers-automatically/
- Compose Healthcheck: https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck
Summary: Docker container healthchecks
Healthchecks are a straightforward way to monitor the actual availability of Docker containers. They can be defined in a Dockerfile or Docker Compose file and work closely with restart policies. For critical AI services like Ollama, Open WebUI, or databases, targeted endpoint checks should be configured. What matters most is choosing sensible intervals, allowing adequate startup time, and using precise check methods. Building in healthchecks early noticeably improves the stability of your entire stack.


