ServerZero: A Raspberry Pi home server

- Hariharan

Why a home server?

I have lately been shifting to more privacy-conscious solutions wherever possible. I switched to a degoogled ROM on my phone and deleted my Gmail account and moved my email to Tutanota under a custom domain. There are many good SaaS offerings available for free but they are not the most privacy-friendly so I had to find alternatives or selfhost. I had tried to selfhost in the past but it never went beyond a few days. I think I was too ambitious and didn’t set an expectation or an objective to achieve which might have led to the failure. This time I set simple goals and tried to only selfhost services that I would really need. Another mistake I had done in the past was to have an unnecessarily complicated architecture. This time I tried to keep everything simple and minimal and so far it has worked. I have been running this for about 2 months now without any major issues.

Objectives

I wanted an internal adblocking DNS. Even though it can’t filter all ads out of the box, there are a lot of community maintained blocklists that can greatly improve the block percentage. I can sleep better at night knowing that the probability of clicking a malicious link would be lower. I also wanted a file server and a media server. I was also interested in hosting some sort of a sync server for notes, calendars, contacts, etc.

The setup should be easy enough to add new services later and generally be easy to maintain. My paranoia didn’t allow me to use a VPS to host my personal data so it had to be inside my home network.

Setup

Flame dashboard

I decided to use a single Raspberry Pi 4 4GB model. I was surprised at how well it can handle the workloads. The reasons behind choosing an RPi were simple -

  1. I had one with me
  2. Power consumption is low
  3. It is cheap and expendable (sort of)

I got a cheap case with a fan to prevent overheating (RPi 4 overheats quite a bit) and I am also booting from an SSD.

Services

Flame - Start page

Jellyfin - Media Server, The files have to be in h264 to use hardware acceleration. Some clients can decode h265 files on the client side but I haven’t tried them yet. Raspberry Pi is not the best platform to run Jellyfin but my library is mostly made up of h264 videos and I am content with the performance.

Miniflux - RSS reader

Joplin Server - Sync server for Joplin, I maintain a separate joplin-server docker image for arm64 and armv7.

Traefik - Reverse proxy, handles certificate renewals as well. Used with docker provider.

Pi-Hole - Adblocking DNS, also used as an internal DNS. Currently uses Cloudflare as upstream but I am planning to move to Unbound.

Etebase - Used as a sync server to sync calendar, contacts, and todo. I maintain a separate etebase docker image for arm64 and armv7.

Grafana - Used to visualize server metrics. I also run Telegraf on the RPi which pushes the metrics to InfluxDB. I am still new to Grafana and primarily use this instance to learn.

Gitea - Lightweight git server, I use this to host projects that are still WIP and before pushing to GitHub.

Gotify - Notification server, I use it in bash scripts and cron jobs to send out notifications to my phone.

Send - A fork of Firefox Send, I currently use it to transfer small files between my phone and PC. I maintain a separate docker image for send as well.

Metube - A frontend for yt-dlp, saves the files to a directory mounted in Jellyfin where I can play the videos later.
Bookstack - Selfhosted wiki, I use it to improve my writing skills.

Qbittorrent - Qbittorrent Web UI

All of these services are run as docker containers using docker-compose. I also run Postgres, InfluxDB, MariaDB, Redis as docker containers. I am using Traefik as the reverse proxy and since I own the domain, it is also able to automatically acquire and renew certificates from Let’s Encrypt.
Pi-Hole also acts as the internal DNS where I have defined the records for all these services.

I also have some cron jobs to shut down the server at 12:00 AM every day and to take backups using rsync to an external drive. Docker makes it really easy to backup and restore volumes.

I actively remove and replace services that I don’t need. The initial set of services had paperless-ng, nocodb, and I even tried hosting nextcloud. But I found out that I don’t have a use for them in my current workflow. Nextcloud is an awesome application but it has too many features that I don’t need right now. I run a Samba server instead. It is easy to find smaller replacements that do one thing but do it really well.

Future

I am very happy with the current setup. I am currently only using it in my home network and I plan on adding Tailscale or just plain old WireGuard to use it from anywhere without having to open any ports. Even though I have automated most of the steps needed to set the server up, I am also experimenting with making it, even more, easier to spin an instance up. Ansible seems like a good short-term solution. For the long-term, I would like to use NixOS or even build a custom distro.

You can find the setup scripts and instructions here.