Skip to content
IgusiusPublic

About

A self-hosted monitoring for a Linux host and its Docker containers. Go, ~11 MB static binary, zero runtime dependencies. monitoring dashboard for one Linux machine and the containers within it.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

Perch

Monitoring for one Linux machine and its Docker containers. One small Go binary, no accounts, no cloud, no agents to install.

Run it on the host you want to watch and it serves a live dashboard of the machine and everything running on it. It only reports on the box it runs on, so to watch several machines, run one instance on each.

The Perch dashboard: machine metrics, containers, health checks and notification webhooks on one page

What you get

  • CPU, memory, swap, load, uptime, disk usage per mount.
  • NVIDIA GPU utilization, VRAM, temperature, power draw.
  • Containers from the Docker API: state, health, live CPU/memory, ports.
  • Per-container log tails.
  • Incoming HTTP requests, read from nginx proxy manager's access logs.
  • Health checks against your own URLs, with latency and uptime.
  • A "curl from the browser" for hitting services from inside the network.
  • A read-only Redis console: run SCAN, INFO, CLIENT LIST and friends against any Redis on the network, from the dashboard.
  • Alerts to a Discord, Slack, or Telegram webhook when a check fails, a container turns unhealthy, or a disk fills up.
  • OpenAI and Anthropic API spend, if you supply org admin keys.
  • Optional login with a shared key or GitHub OAuth.

Quick start

export PERCH_KEY=$(openssl rand -hex 24)
docker compose up -d

That starts Perch plus a read-only Docker socket proxy. The dashboard listens on 127.0.0.1:3535, so it is reachable from the host but not from the internet. To see it from your laptop:

ssh -L 3535:localhost:3535 you@your-server

For permanent access, put it behind a reverse proxy over HTTPS. Don't publish 3535:3535 on a public server; published Docker ports bypass ufw/firewalld.

Health checks are added from the dashboard and persist in the /data volume.

From source

go run .

Then open http://localhost:3535. Auth is off unless ACCESS_KEY is set. On WSL2 you need Docker Desktop's WSL integration enabled for the Containers tile to work.

Configuration

A .env file in the working directory is loaded on startup; the real environment wins over it.

Env var Default Purpose
ACCESS_KEY (empty = auth off) login key; compose wires PERCH_KEY into it
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET (empty = off) GitHub OAuth App credentials
GITHUB_ALLOWED_USERS (empty) usernames allowed to sign in, comma-separated
GITHUB_ALLOWED_EMAILS (empty) verified emails allowed to sign in, comma-separated
RATE_LIMIT / RATE_WINDOW_SECONDS 50 / 10 unauthenticated requests per IP per window
BAN_HOURS 10 how long an over-limit IP stays banned
BAN_FILE /data/banned_ips.txt ban persistence
PORT 3535 listen port
CHECKS_YAML (empty) health checks declared up front, instead of adding them in the UI
NPM_LOG_DIR /npm-logs nginx proxy manager access logs
REDIS_TARGETS (empty) Redis addresses the console may reach, comma-separated (cache=redis:6379, redis-2:6379); empty means any address, with no stored credentials
REDIS_USERNAME / REDIS_PASSWORD (empty) credentials for the REDIS_TARGETS above; only ever sent to those addresses. Typed per query otherwise
ALERT_WEBHOOK_URL (empty = alerts off) Discord, Slack, or Telegram webhook; also settable in the UI
ALERT_DISK_PCT 90 percent-full at which a disk alerts
OPENAI_ADMIN_KEY / ANTHROPIC_ADMIN_KEY (empty = tab off) org admin keys for the spend tab, read server-side only
DOCKER_HOST (unix socket) tcp://socket-proxy:2375 for proxied access
HOST_PROC / HOST_SYS / HOST_ROOT (the container's own /proc, /sys, /) where the host's proc/sys/rootfs are mounted; the compose file sets these to /host/*
NVIDIA_SMI_PATH (auto-detect) explicit nvidia-smi location

For GitHub login, create an OAuth App with callback URL https://<your-domain>/api/auth/github/callback, then set the client ID, secret, and an allowlist. Only usernames and verified emails are matched, never display names.

Security

The Docker socket is never mounted into Perch. A socket-proxy forwards read-only GET /containers/* calls and rejects everything else, so a hijacked Perch cannot start, stop, or remove containers. The container drops all capabilities and runs with a read-only root filesystem and read-only host mounts.

Perch only reads. There is no start, stop, restart, or redeploy; every Docker call it makes is a GET.

The Redis console does not use docker exec. Perch speaks the Redis protocol over the network, so the console needs no Docker privileges at all, and the command allowlist lives in the server. Commands that write, reconfigure, run scripts, or stop the server are refused before a connection is opened. Credential values in a CONFIG GET reply are redacted, matched on the shape of the parameter name so a renamed spelling does not slip through.

REDIS_USERNAME/REDIS_PASSWORD are only ever sent to an address listed in REDIS_TARGETS. Without that list Perch never sends them at all, and you type the password per query instead. This is deliberate: the console target is free text, so a stored credential paired with an arbitrary address would let any logged-in user point Perch at a host they control and collect it. Setting REDIS_TARGETS also stops the console reaching anything else on your network.

It can still read your data, which is the point of it: anyone who can log in to Perch can read any Redis Perch can reach. Give Perch a read-only Redis ACL user and let Redis enforce the limit too.

The API-calls feature sends its requests from the Perch container, so a logged-in user can reach anything the container can reach on your internal network, including a cloud provider's metadata endpoint.

License

MIT.

About

A self-hosted monitoring for a Linux host and its Docker containers. Go, ~11 MB static binary, zero runtime dependencies. monitoring dashboard for one Linux machine and the containers within it.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages