DockLogDockLogBlog
6 min readDockLog

Self-hosted container monitoring on a budget

How to monitor Docker and Kubernetes containers self-hosted without SaaS bills: logs, metrics, uptime, and alerts on a single VPS or homelab.

Self-hosted container monitoring is attractive for the same reason self-hosted Git is: your logs and metrics stay on hardware you control, predictable cost, no per-host pricing surprise.

The tradeoff is you become the platform team. The goal is not "run everything CNCF." The goal is knowing when something breaks before users email you, without a $400/month observability bill.

What "monitoring" means on one box

SignalCheap self-hostedHeavier option
Container aliveDocker healthchecks, restart policyOrchestrator probes
LogsDockLog, DozzleLoki, OpenSearch
CPU / RAMdocker stats, DockLog, cAdvisorPrometheus + Grafana
HTTP upUptime Kuma, healthchecks.io self-hostedSynthetic SaaS
AlertsDockLog webhooks, AlertmanagerPagerDuty

A $6 VPS can run row one through four if you are disciplined about RAM.

The mistake is treating "monitoring" as one install button. You need at least three signals: process health (is the container up), application signal (what did it log), and user-visible health (can the public URL load). One tool rarely covers all three well.

Reference architecture: single VPS

Typical DockLog user setup:

text
Internet
   |
[Caddy / nginx TLS]
   |
+-- DockLog (logs, optional CPU alerts, RBAC)
+-- Your app containers (compose)
+-- Uptime Kuma (optional, external checks)

Everything on one host shares kernel and disk. Set log rotation on every service. Docker log management covers max-size.

Auth on DockLog before port forwarding. DISABLE_AUTH is for localhost smoke tests only. Compose production setup.

Minimal compose sketch

You do not need a bespoke stack on day one. A single compose file can hold your app plus DockLog plus Uptime Kuma:

yaml
services:
  docklog:
    image: aimldev/docklog:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - docklog_data:/data
    environment:
      - SECRET_KEY=${SECRET_KEY}
      - DB_PATH=/data/users.db
    restart: unless-stopped

  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - kuma_data:/app/data
    restart: unless-stopped

Put TLS on Caddy in front of both. DockLog and Kuma on separate subdomains keeps cookie and WebSocket config simpler.

Reference architecture: k3s homelab

text
k3s cluster
   |
+-- metrics-server (kubectl top, HPA)
+-- DockLog (in-cluster SA or kubeconfig, namespace RBAC)
+-- ingress with TLS
+-- optional: kube-prometheus-stack if you outgrow top

Kubernetes monitoring guide walks tool choice. K8s log tailing for DockLog specifics.

Hybrid setups are common: production apps on Docker Compose, staging on k3s, same physical machine or two VPS instances. DockLog RUNTIME_MODE=both gives one UI for both runtimes if you accept the security implications of socket plus kubeconfig on one host.

RAM reality check

Rough order of magnitude on amd64:

ComponentRAM
DockLog~30 to 50 MB
Dozzlesimilar class
Uptime Kuma~100 to 200 MB
Prometheus (small)500 MB to 2 GB+
Grafana200 to 500 MB
Loki (small)500 MB to several GB

If you have 2 GB total on the VPS, pick one heavy item or none. Tail logs + uptime checks beats half-working Prometheus.

Leave headroom for your actual apps. Monitoring that OOMs the host is worse than no monitoring.

Disk matters too

Logs, Prometheus TSDB, and Uptime Kuma history all grow. On a 20 GB VPS:

  • Set max-size / max-file on every container (log management guide)
  • Put Prometheus retention at 7d until you have a reason for more
  • Monitor disk at 85% with a simple cron script or node exporter

A full disk stops writes everywhere, including the database inside your app container.

Self-hosted vs SaaS (honest)

Choose self-hosted when:

  • Data residency matters
  • Host count is stable and low
  • You already SSH to the box weekly

Choose SaaS when:

  • On-call rotation needs mobile app and escalation policies day one
  • Traces and APM across 50 microservices
  • No one wants to upgrade Grafana plugins

Hybrid works: self-hosted tail on staging, Datadog on prod, same debugging habits.

SaaS per-host pricing hurts when you run twelve small containers on one VM. Self-hosted flat cost wins until you need enterprise features (trace correlation, ML anomaly detection, compliance exports).

Alerts that fit self-hosted

Webhook to Slack, Discord, or Teams is enough for many teams. Alert setup guide.

Good first rules:

  • Container restart loop (Docker event or log pattern)
  • Disk above 85% on the host (node exporter or simple cron script)
  • HTTP check failed twice in a row
  • K8s Warning event for FailedScheduling or BackOff

Bad first rules:

  • Every log line containing "error"
  • CPU above 50% for 30 seconds

Tune alerts against real incidents. If a rule fired during every deploy last month, narrow it (specific container, longer window, exclude known maintenance window).

Alert routing without PagerDuty

Small teams often use:

  • Slack channel #alerts-staging for noisy early rules
  • #alerts-prod for rules that wake someone
  • DockLog native app for Docker events when you are away from laptop (native apps post)

Escalation policies are manual ("if nobody acks in 15 minutes, call Bob"). That is fine at five people.

Security is part of monitoring

A monitoring UI with Docker socket or cluster admin is a crown jewel.

  • TLS everywhere user-facing
  • TRUST_PROXY when behind reverse proxy
  • Strong SECRET_KEY, persistent DB_PATH for users
  • Firewall: only 443 public, SSH on non-default or VPN
  • Reverse proxy hardening

Monitoring tools are high-value targets. An attacker with your DockLog admin password can read logs (often secrets), restart containers, and pivot. Use strong passwords, per-user accounts, and audit logs when the team grows past two.

Tool picks we see work

  • Solo homelab: Dozzle or DockLog + Uptime Kuma
  • Small agency VPS (multi-client): DockLog with allowed_containers patterns per user
  • k3s staging + Docker prod on same metal: DockLog RUNTIME_MODE=both
  • Metrics-curious: cAdvisor scraped occasionally before full Prometheus commit

Full market map: Docker monitoring tools 2026.

Monitoring your monitoring

Self-hosted means you own uptime of the uptime checker.

Practical habits:

  • Run Uptime Kuma (or similar) on the same host but monitor external URLs, not only localhost
  • Use a second cheap VPS or a friend's server to ping your main ingress (even a free tier works)
  • Document "how to tail logs if DockLog is down" (SSH plus docker logs fallback)
  • Back up DB_PATH and Uptime Kuma's data volume with the same schedule as app databases

If the only monitor runs on the box that died, you will not get the alert.

Upgrade path

  1. Week 1: log viewer + rotation + TLS
  2. Week 2: one Slack alert that matters
  3. Month 2: uptime checks on customer URLs
  4. When prompted by incidents: Prometheus or Loki, not before

Self-hosted container monitoring fails when teams install the enterprise stack on a laptop-class server. Start small, measure RAM, add weight when a real ticket justifies it.

Continue reading