Energy-sober self-hosting on consumer hardware. The idea: a home server that sleeps when idle and wakes on demand, so a repurposed desktop (here an i7-6700 / 32 GB) can host a dozen services without burning power 24/7.
This repo extracts the reusable, non-obvious pieces from a running setup. It is a set of patterns and sanitized examples, not a one-command deploy. Copy what you need.
| Piece | File | Why it's worth copying |
|---|---|---|
| On-demand containers | docker-compose.yml + config/caddy/Caddyfile |
Heavy services (Collabora, Ollama) are stopped by Sablier and started only when a request hits their Caddy vhost. |
| Collabora healthcheck fix | docker-compose.yml (collabora block) |
The image is distroless: no curl, no shell. Every home-made probe fails forever and flags the container unhealthy. Inherit the image's own healthcheck instead of writing one. |
| Multi-DB offsite backup | scripts/backup.sh |
Consistent dumps of Postgres + MariaDB + SQLite (with the readiness/permission gotchas solved) → rclone encrypted remote → webhook notification. |
| Wake-on-LAN relay | scripts/wol-relay.sh |
Wake a LAN machine from anywhere by relaying the broadcast through an always-on Tailscale node. |
Two moving parts:
- Sablier watches Docker. Containers labelled
sablier.enable=true+sablier.group=<name>are stopped when idle. - Caddy (built with the Sablier plugin, see
config/caddy/Dockerfile) gates a vhost behind a group. The first request wakes the group, shows a loading page, then proxies through.
sablier http://sablier:10000 {
group ai
session_duration 30m
}
reverse_proxy open-webui:8080
Result: Ollama and friends consume nothing until someone actually opens the chat UI, then spin down 30 min after the last request.
Gotcha worth knowing: if a whole service is gated behind a group whose healthcheck is red, Sablier serves its loading page for every request, including WebDAV. A broken healthcheck therefore breaks Nextcloud sync silently, which is exactly what the Collabora healthcheck fix prevents.
Follow-up from running this for a year: keeping that healthcheck green is not enough, because it makes the gated service's health a dependency of the whole vhost. Gate only the paths that need the on-demand service (see the
:8081block inconfig/caddy/Caddyfile). Two things improve at once: sync and mobile clients stop caring whether Collabora is alive, and Collabora actually gets to sleep, since sync traffic no longer refreshes its Sablier session every few minutes.
cp .env.example .env # fill in DOMAIN, DB passwords, rclone remote, webhook
docker compose up -dThe Caddyfile expects a Tailscale MagicDNS hostname in DOMAIN and the
tailscaled socket mounted (see the caddy service). Adapt to plain TLS if you're
not on Tailscale.
Personal config, secrets, and one-off glue are stripped. This is the skeleton — bring your own services, volumes, and domains.
MIT