One of my biggest, longest-running personal projects is my personal home server.
This is a project that I've used to replace closed-source, corporate-owned cloud services in my digital life (e.g. PhotoPrism has replaced Google Photos), and also to develop and host some brand new automation systems (such as my Personal Finance Dashboard).
Software
This is an ever-evolving list of software and services that are being run on my server. I'll keep this up to date as further developments come along!
OS
I'm running Ubuntu Server 22.04. I only ssh into this machine and have no need for a GUI, since all of the services that are hosted on the machine will be accessed and managed through a web UI.
eric@basingse:~$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Installed Packages
The only package that I've installed using a package manager is Docker (literally). Every hosted service is running containerized.
I set it up this way so that I wouldn't have to create (and backup) a custom OS image from which to restore in case of catastrophe. This way, I only have to backup my Docker volumes and my home directory (which also contains my Docker Compose file). If I ever need to restore from scratch in the future, I only need restore these two directories and install Docker and I'll be up and running.
One note here is that I opted for Docker on this project due to already having familiarity with it through my work. One of the TODOs on this project are to replace Docker with Podman/Kubernetes.
Services
This is a steadily growing list of services that I have running on my server for various reasons.
- Cloudflared Tunnel - this is the reverse proxy between my server and the public internet. I opted for the CF Tunnel instead of a more traditional, open-source solution because my network is currently behind a CGNAT and this was the most accessible solution that I was able to find when initially setting up my host. A big thing on my TODO list is to replace this with a FOSS, privacy-friendly alternative
- Nextcloud - cloud services (storage, contacts, calendar) provider
- Protonwire - Proton VPN used for concealing the IP of other services
- Caddy + caddy-security - used as a 2FA authentication layer for other services
- Jellyfin - media server front-end
- Jellyseerr + Radarr/Sonarr + Jackett + qbittorrent + Unpackerr + Flaresolverr - media management pipeline for Jellyfin
- Bazarr - automated subtitle management for Jellyfin
- Tdarr - automated file encodes for stream optimization for Jellyfin
- PhotoPrism - personal photo library management
- Cronicle - scheduled task management with an accessible front-end
- Protonmail Bridge - SMTP provider for Proton Mail that is used for automated email notifications from various services. Note that I need a separate instance of this running for each Docker network running on my device, so I actually have three containers running this image (one each for my host network, VPN, and Nextcloud)
- Prometheus + Node Exporter + Process Exporter + Alert Manager + Push Gateway - metrics stack for aggregating and reporting on device hardware health
- Grafana - front-end metrics visualization, currently used with Prometheus for a device health dashboard accessible from the web
- Gotify - push notification service used to automated alerting of configurable events. This was being used when I was searching for a GPU 😄
- Webhook - used for accepting HTTP requests and doing something when they come in. At the moment, this is used to write my incoming SMS messages from my phone to my server
- Bitwarden REST API Server - a REST API server used for accessing my secrets stored in Bitwarden
- Badge Server - a Flask-based badge server which is used to update and serve SVG images for badges that I refer to in some GitHub documentation
- Ghost - a self-hosted blogging platform that you're reading right now ;)
As mentioned above, all of these services are running containerized and are not installed natively. All of these services are free and open source, with the lone exception of Proton Mail/Bridge being a paid service (Proton Mail has a free plan that doesn't include bridge usage).
Feel free to check out and use the docker-compose.yml
file that I use on my host to manage this environment. Hopefully this can help avoid some of the debugging and headaches that I went through getting everything up and running 😄
All secrets and endpoints are parameterized and kept in an .env
file in my home directory, where docker-compose.yml
is also stored, making this config perfectly replicable if I ever migrate to a new device.
Additionally, all mounted volumes are kept at /etc/docker/{container-name}
, making it easy to track, backup, and restore my environment.
Hardware
Here's the build:
A few notes:
- 4 x 8tb storage drives in Ubuntu's native software RAID5 = 24tb storage partition mounted at
/media/md0
- Most likely way overkill on the RAM, but I had some extra room in the budget
- I'm not transcoding any video when streaming through Jellyfin, hence no need for an excessively powerful CPU. Instead, I am re-encoding files for optimal streaming when they're processed in my video pipeline using Tdarr. One TODO on my project list is to build a CPU-heavy machine strictly for re-encoding and having that operate separately from the server
- Probably overkill on the wattage for the PSU, but I wanted Platinum grade efficiency, and this is pretty much the only option for mITX form factor. Plus, I've used this PSU before and absolutely love it, so there's that
Conclusion
That's the basics of my setup! I'll be writing more detailed articles on various parts and decisions of the build, and updating this piece as time goes on.
Feel free to leave thoughts below! I'd love to hear any feedback or answer any questions on the system.