Lightweight host monitoring with Docker-based clients and a central server. Clients collect system metrics every 30 seconds and send them to a server, which stores the data and exposes it via Web UI and REST API.
- Python 3.12
psutil,requests- Runs in Docker with host access:
pid: hostnetwork_mode: host- read-only mounts of
/,/proc,/sys
- Supported OS:
- Raspbian (RPi 3B+, 4B, ARM64)
- Debian (x86_64)
- No Windows support
- Python 3.12
- FastAPI + Uvicorn
- PostgreSQL 16
- SQLAlchemy (ORM)
- Jinja2 (simple Web UI)
- REST API for external frontends
- Healthchecks (liveness + readiness)
- Docker
- Docker Compose
- Environment-based configuration via
--environment
- Docker ≥ 24
- Docker Compose v2
- Linux host (ARM64 or x86_64)
monitoring/
├─ docker-compose.yml
├─ run.sh
├─ env/
│ ├─ dev.env
│ └─ prod.env
├─ client/
│ └─ (client code)
└─ server/
└─ (server code)
Create or adjust environment files:
env/dev.env– local developmentenv/prod.env– production
Key variables:
SERVER_URL=http://<server-host>:8000
DATABASE_URL=postgresql+psycopg://user:pass@db:5432/monitoring
CLIENT_ID=host # optional, defaults to "host"
INTERVAL_SECONDS=30
INGEST_API_KEY=change-meUse this mode on monitored hosts (Raspberry Pi, Debian, etc.).
Only the client container will be started.
./run.sh --environment prod --client-only up -d --build
./run.sh --environment prod --client-only logs -f
./run.sh --environment prod --client-only down
- The host running the client is always identified as host (unless CLIENT_ID is explicitly set).
- Metrics are collected from the host system, not the container.
- Data is sent every 30 seconds.
Use this mode on the central monitoring server.
This starts:
- PostgreSQL
- Monitoring server (FastAPI)
./run.sh --environment prod up -d --build
./run.sh --environment prod logs -f
./run.sh --environment prod down
http://<server-host>:8000
- Liveness:
GET /health/live - Readiness:
GET /health/ready
- List Clients
GET /api/clients - Latest Metrics for a client:
GET /api/clients/{client_id}/latest - Metrics history (last 24h):
GET /api/clients/{client_id}/metrics?limit={<limit (max 2880)>}
- enforced server-side
- per client:
- last 24 hours only
- implemented as time-based cleanup on ingest
- No cron jobs
- Database Size remains bounded
-
one server
- runs
db + server
- runs
-
many clients
- each host runs
--client-only - all send data to the same server
- each host runs