Homelab
The services I run for myself under hutnan.dev, on one small Hetzner VPS in the EU, because where my data is stored matters to me. Everything is a Docker Compose stack, and everything public sits behind a single Caddy proxy.
How it's run
Lean on purpose
Each service is the lightest tool that does the job. That keeps the attack surface small enough to reason about, and fits everything on a budget VPS.
One proxy, configured by labels
Caddy runs with caddy-docker-proxy. Every public stack joins one Docker network, web, and declares its domain in Compose labels; Caddy serves it over HTTPS with automatic certificates. The same labels feed a Homepage dashboard, so a new stack gets its tile automatically.
Admin off the internet, nothing hidden
Paperless, Dockge and Glances are reachable only over Tailscale. The rest is listed here on purpose: each service has its own strong password, and nothing depends on an address staying secret.
Backups off the box
restic pushes the data and the Compose files to Cloudflare R2 object storage.
Updates by hand
I review and apply container updates in Dockge, and update the server myself, only when I have time to fix whatever breaks. Nothing updates on its own, so a key service never breaks at a bad moment.
What's next
Glances shows the server filling up, and Paperless spikes the CPU while it OCRs an upload. The likely next step is a second VPS that runs only the core services.
On the internet
Each on its own subdomain, behind Caddy.
Forgejo
Git hostingHolds my Obsidian vault, one of the most personal things I own. It's mostly plain text and I want its full history, so it belongs in Git, just not on a public Git host.
git.hutnan.dev ↗Live
Live presentationsMy own service for teaching from Quarto reveal.js decks: students type the session code on its home page, follow on their own screens and ask questions while I draw on the slides.
live.hutnan.dev ↗Seafile
Files and driveMy Google Drive replacement for whatever doesn't fit Paperless or Git: school presentations, PDF assignments, large binaries and the sheets for shared finances and split bills. Nextcloud was far more than I needed.
drive.hutnan.dev ↗SearXNG
Metasearch engineThe default search on my laptop, iPad and GrapheneOS phone. It queries several engines at once, without tracking or ads.
search.hutnan.dev ↗Vaultwarden
PasswordsReplaced years of Firefox's built-in passwords, which always felt too exposed. The official Bitwarden apps encrypt the vault on my devices, so the server only ever stores ciphertext.
vault.hutnan.dev ↗Xandikos
Contacts and calendar syncCardDAV and CalDAV for one person, with no accounts to create or secure. Thunderbird syncs it on my laptop; DAVx⁵, Fossify Calendar and the contacts app on my phone.
dav.hutnan.dev · sync only
Tailscale only
Tools that control the server or hold my documents, so only my own devices can reach them.
Paperless-ngx
Document archiveEvery important document, uploaded and tagged through its web interface and OCR'd locally so it's searchable. That OCR is also the server's biggest CPU spike.
TailscaleDockge
Stack managerA web UI over the Compose files, and where I review and apply every update. It does what I need from Portainer without the heavier UI or Kubernetes support.
TailscaleGlances
System metricsCPU, memory, disk and container usage. Lately it shows the server filling up.
Tailscale
Off the server
Part of the setup, but hosted elsewhere.
This site
PortfolioHosted on GitHub Pages.
hutnan.devDrill
Practice testsHosted on GitHub Pages.
drill.hutnan.devDomain and backups
Registrar and storageHosted on Cloudflare.
R2 object storageMail
EmailHosted on Purelymail.
tomas@hutnan.dev