Running services in Docker containers gives you isolation and reproducibility — but containers also introduce new failure modes that traditional monitoring misses. A container can crash silently, expose a port that goes unreachable, or fail its own health check without anyone noticing for hours.
In this tutorial you'll set up end-to-end monitoring for Docker services using Vigilmon — free tier, no credit card.
Why containers need dedicated monitoring
Docker containers fail in ways that VM-era monitoring tools weren't built to catch:
- Silent crash and restart loops — a container restarts every 30 seconds (crash-loop), appears "running" at the Docker level, but never serves traffic
-
Port-binding failures — the container starts but the host port binding silently drops;
curl localhost:3000hangs indefinitely -
Health check mismatches — you define a
HEALTHCHECKin your Dockerfile but never alert on anunhealthystatus -
Dependency failures — your app container is up but the database container it depends on is down, making your
/healthendpoint return 500
External monitoring — something probing your service from outside the Docker network — is the only way to catch all of these reliably.
What you'll need
- A running Docker service (we'll use a sample
docker-compose.yml) - A free Vigilmon account (sign up takes 30 seconds)
Step 1: Add a health endpoint to your Docker service
Before setting up a monitor, give Vigilmon something to check. Add a /health route to your app that returns HTTP 200 when the service is operational.
Here's an example for a Node.js/Express app already in your container:
// Add to your Express app
app.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
For a Go service:
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"ok"}`))
})
Expose the port in your docker-compose.yml:
version: "3.9"
services:
web:
image: your-app:latest
build: .
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
db_data:
The healthcheck block tells Docker when your container is healthy — but Docker doesn't alert you when it goes unhealthy. That's where Vigilmon comes in.
Step 2: Set up HTTP monitoring in Vigilmon
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS as the type
- Set the URL to your health endpoint, e.g.
https://your-server.example.com/health - Set the check interval to 1 minute (the free tier supports 1-minute checks)
- Under Expected response, set:
- Status code:
200 - (Optional) Response body contains:
"status":"ok"
- Status code:
- Save the monitor
Vigilmon will now probe your /health endpoint from multiple regions every minute. If it returns anything other than 200 — or if it times out — an incident is triggered.
Step 3: Set up TCP port monitoring
HTTP checks verify that your app is responding correctly. TCP port checks verify that the port is reachable at all — useful for databases, message queues, or any service that doesn't speak HTTP.
- In Vigilmon, go to Monitors → New Monitor
- Choose TCP Port as the type
- Enter your server hostname and the port, e.g.
your-server.example.com/5432 - Save the monitor
Now you'll know immediately if the PostgreSQL container loses its port binding, even before any HTTP-level check would fire.
Step 4: Configure webhook alerts for container downtime
When a container goes down, you want to know in seconds — not when a user reports it. Vigilmon supports webhooks for real-time alerts.
- Go to Alert Channels → Add Channel → Webhook
- Enter your webhook URL (Slack, Discord, PagerDuty, or any custom endpoint)
- Assign the channel to your monitors
Example Slack webhook payload Vigilmon sends on an incident:
{
"monitor_name": "web /health",
"status": "down",
"url": "https://your-server.example.com/health",
"started_at": "2024-01-15T10:23:00Z",
"duration_seconds": 45
}
You can also use email alerts if you don't need real-time Slack notifications — just add an email alert channel and assign it the same way.
Step 5: Create a public status page for your Docker services
If you're running production services, a public status page lets your customers self-serve instead of emailing support when something's down.
- In Vigilmon, go to Status Pages → New Status Page
- Give it a name (e.g. "Production Services")
- Add your monitors —
web /health, TCP postgres:5432, etc. - Publish the page
You'll get a public URL that shows real-time uptime for each monitored service. Share it in your README, your app's footer, or your support docs.
Putting it all together
Here's the complete docker-compose.yml with health checks for all services:
version: "3.9"
services:
web:
image: your-app:latest
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
depends_on:
web:
condition: service_healthy
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
volumes:
db_data:
And the corresponding Vigilmon monitors to set up:
| Monitor | Type | What it catches |
|---|---|---|
https://your-domain/health |
HTTP | App crashes, 5xx errors, DB connection failures |
your-server:80 |
TCP | nginx port binding failures |
your-server:443 |
TCP | TLS/HTTPS port issues |
What's next
- SSL expiry monitoring — Vigilmon also checks your TLS certificate expiry date and alerts you before it lapses
- Heartbeat monitoring — if you run cron jobs or batch tasks inside containers, Vigilmon's heartbeat monitors will alert you when a scheduled job stops reporting in
Get started free at vigilmon.online — no credit card, monitors start running in under a minute.
Top comments (0)