my home server


motivation

I wanted an easy and cheap place to deploy side projects, especially ones which require storage. I'm also squeamish about handling authentication/authorization on publicly accessible stuff. With my own server I can deploy small apps for myself and friends without sweating about sudden spikes in cost, or a mis-configuration exposing my friend's emails.

overview

Multiple apps, APIs, and databases run with podman-compose on one server. Apps are exposed to a tailscale network via tailscale serve. Access to each app requires being on the tailnet and being granted access in a tailnet ACL policy.

hardware

Bought from ebay December 2023 for about $800. I wanted a small form factor with at least 16 GB RAM and a decent CPU.

software

why debian

I wanted Linux because I'm comfortable using that from work, and it makes using Docker easier. I considered Alpine but decided against it because I've had issues fighting musl in the past for libraries with native extensions. I also considered Ubuntu but am not a fan of snaps.

why tailscale

I knew before I even bought the server that I'd be using tailscale. Tailscale is some of the best software I've used, it's made it easy to share my server with friends while not having to make it publicly accessible. Its ACLs also made it easy to control who can see specific apps, so for example my spouse and I have access to a self-hosted financial app, but no one else in my tailnet is. It's also a cheap way to do multi-tenancy, as I can deploy the same app multiple times on different ports, then control who can see each instance.

why ufw

I use tailscale to SSH and allow network access to applications, so I don't need anything publicly accessible at all. Tailscale has documentation on how to use UFW to prevent all external access.

why containers and compose

I'm a big fan of Docker and docker-compose. Docker makes things repeatable, so I can still run an app I haven't touched in years. Compose is dead simple to run an API and its frontend, with a volume, and some environment variables (though I wish it used anything other than YAML). I considered some simplified Kubernetes like k3s or minikube, but I don't need auto-scaling or high availability so Kubernetes is overkill. And frankly I don't find Kubernetes particularly fun so I don't want to spend my free time on it.

why podman instead of docker

I actually started with vanilla Docker but quickly discovered it is incompatible with UFW. Podman has been mostly a drop-in replacement, other than some permission issues with volumes and ports since podman runs rootless.

last updated 2024-02-24