Notes from a year on a five-euro VPS in Helsinki
A year ago I moved this site and a handful of small services off a managed platform onto a single VPS in Helsinki. It costs about five euros a month, has two cores and two gigabytes of memory, and it has taught me more about operations than the platform did, mostly by breaking.
What runs on it
- nginx serving static files, because that is what nginx is good at
- two small Go services and one C++ service, all under systemd
- PostgreSQL for one of them, SQLite for the rest
- certbot renewing certificates on a timer
No Docker. Not out of principle — I like containers — but on two gigabytes the orchestrator is a significant part of the budget, and three units under systemd start in under a second and restart themselves when they crash.
What actually broke
Disk, twice
The first time it was PostgreSQL logs. The second time it was my own mistake: a service writing a debugging line per request and never rotating. Both times the filesystem filled up quietly and the first symptom was something unrelated failing. Now there is a cron job that mails me above 80 percent, which is embarrassing and completely effective.
Certificates, once
A renewal failed because an old domain no longer resolved, and the timer kept retrying the same broken set. Everyone knows about monitoring certificate expiry and almost nobody does it. A one-line check that curls each hostname and reports the days remaining fixed it.
Memory, regularly
Two gigabytes sounds like plenty until a Go service with a large cache and a database
with default settings both decide they want it. Setting shared_buffers to
something honest and giving the cache a limit solved it. The OOM killer is not a monitoring
tool.
What I would do again
- Debian stable, unattended-upgrades, nothing else installed that is not needed.
- Backups to object storage with restic, checked by restoring once a quarter.
- Logs to
journaldwith a size limit, not to files that grow forever. - One cron entry that mails a short status line every morning: disk, memory, load, certificate days left, last backup age.
That last item is maybe ten lines of shell and it has caught every incident since.
What I would not do again
I spent an unreasonable amount of the first month on configuration management for a
single host. Ansible is a good tool and it was the wrong tool for three services and one
person. A directory of files, rsync, and a short README is enough until the
second machine exists.