OMV RPi5 Server
Disclaimer: everything expressed in this post is my own opinion.
In this post I'll be discussing the design motivation for my self-hosted media server using OMV, Tailscale, Immich and NextCloud, and the Raspberry Pi 5. I was inspired to do this project since a couple friends of mine recommended checking out Tailscale - a free mesh VPN that connects clients/servers in a secure peer-to-peer manner. I also wanted to experiment sharing files via Cloud Federation from my NextCloudPi https://www.ianwebster.ca/post/nextcloudpi running on the other side of the country. I had no formal requirements for this project as it was purely a passion project for exploration and learning!
Build guide here: https://www.ianwebster.ca/post/omv-rpi5-build-guide!
To make this all happen, I had to choose a hardware platform first. The Raspberry Pi has been a long-time favourite of mine since it is one of the smallest form-factor consumer SBCs (single-board computers) out there. There are many alternatives to the Raspberry Pi 5, including the Rock 5C https://radxa.com/products/rock5/5c and Odroid. I chose the 8GB RAM model since I plan to use the ZFS filesystem for redundancy and data durability, and ZFS requires large amounts of memory to cache files.
While choosing an x86 platform makes more sense from a budget and platform compatibility perspective, I chose to use the Raspberry Pi 5 (RPi5) on arm64 to keep the form factor as small as possible. Other benefits to choosing a RPi5 (and most other SBCs on arm64) include its 1) near silence at load even with a CPU cooler, 2) low power draw, and 3) GPIO expansion header for hardware hacks. If you are considering building a home server and you would prefer performance over all else, then it makes more sense to reuse an old desktop/laptop, buy a second-hand Dell WYSE 5070 Thin Client, or buy a FriendlyElec CM3588 (these options are less DIY though).
One other advantage of choosing the RPi5 is that there are multiple expansion boards designed for it. Critically, there is a company called RADXA that designed a hardware "hat" (expansion board) that allows you to wire up 5 SATA drives to your Pi 5 via the Pi's FPC (flexible printed circuit) connector (PCIe 2.0 x1). I discovered this RADXA Penta SATA Hat through a Jeff Geerling post https://www.jeffgeerling.com/blog/2024/radxas-sata-hat-makes-compact-pi-5-nas which you should go check out! My hardware guide is based on Jeff's youtube video https://www.youtube.com/watch?v=l30sADfDiM8 and Michael Klements' video https://www.the-diy-life.com/i-built-a-4-bay-raspberry-pi-5-based-nas/.
With 4 SATA SSDs or equivalent 2.5" HDDs, the RPi5 and SATA Hat form factor sits at roughly 5cm x 9cm x 13cm - a volume unbeatable only by perhaps an equivalent 4x NVME hat in a horizontal layout. Unfortunately, NVME drives and hats are more expensive, and at a higher price point, I would rather invest in a proper x86 rack for serious home lab experiments. You can read more on NVME performance on the RPi5 in Jeff Geerling's post: https://www.jeffgeerling.com/blog/2024/4-way-nvme-raid-comes-raspberry-pi-5.
One caveat of choosing the Raspberry Pi5 with the RADXA Penta SATA hat is that you will need an RPi5 cooling fan to keep the Pi CPU temperature regulated under load, and the RADXA Penta SATA hat is not compatible out-of-the-box with the RPi5 cooling fan. The popular solution in Jeff/Michael's videos are to crimp off 3 fins using a pair of pliers to make space for the SATA hat over the RPi5 cooling fan's heatsink. If breaking off heat fins isn't your thing, it's probably best to consider a different platform for your home server!
I chose to boot the RPi5 from a 32GB SanDisk (at least Class 10) microSD card. While microSD cards are not known for durability, they will serve well for a non-critical workload. You could also use one of the SATA ports on the hat for a boot SSD if you want a more durable solution.
I chose a storage capacity (2TB, mirrored) that I expected to fill up to 50% within my first year of use. I chose a Teamgroup SSD with the lowest cost per terabyte with a high TBW (terabytes written, i.e. longest expected lifespan, ignoring MTBF). The 2TB T253A3002T0C101 SSDs are rated for 400TBW and have sequential read/write speeds up to ~500MB/s. NVME SSDs can achieve 15x or more compared to these speeds, but in my case, the storage performance bottleneck will be the client devices, home network, and external networks accessing the drives, not the SSDs themselves.
The RPi5 1Gbps (1Gbps = 125MB/s theoretical line speed) NIC will serve appropriately since I won't be accessing the server from many concurrent connections at once. You can buy a 2.5Gbps USB NIC for the Pi, and (theoretically) leverage these faster speeds (312MB/s) if you have a compatible 2.5Gbps network switch or router. It is worth noting that the RPi5 shares its PCIe lanes across the USB, ethernet, display, and GPIO, and so you will need to trade off network and storage speeds. Interestingly, you can increase the external PCIe speeds to Gen 3.0 @ 8GT/s (instead of Gen 2.0 @ 5GT/s) to get faster speeds from your SATA drives on the PCIe hat. At the time of writing this post, you cannot increase the speed of the internal lanes.
As an alternative to the USB NIC, you could use a PCIe NIC paired with an FPC PCIe Breakout hat to connect both the PCIe NIC and SATA hat simultaneously to the Pi. Since the external PCIe speeds can be increased to Gen 3.0 speeds, it makes sense to use a USB NIC instead of a solution relying on an FPC PCIe Breakout hat + PCIe NIC + SATA hat. The USB NIC solution allows you to make use of the higher Gen 3.0 speeds for storage, and leave the USB network NIC on the slower Gen 2.0 PCIe lanes. In my case, I wanted to keep costs low, so I did not entertain full 2.5Gbps in-home networking.
To decide on the power supply, I considered the power draw of the Pi and any external devices connected to it. I roughly estimated the Pi and SATA hat would draw 6W + 3W per SSD = 12W. I chose a USB-C power supply capable of delivering 5.2V @ 3A = 15.6W.
If you want more headroom, you can always buy a power adapter like this 12V @ 5A = 60W power supply (https://a.co/d/hpBcxxr), which powers the Pi directly, along with the SATA hat and drives. 60W is enough headroom to power multiple 2.5" HDDs, or possibly a few 3.5" HDDs. Note, the RADXA Penta SATA Hat has 4 fixed SATA Data + Power (22 pin) combo connectors, and 1 external eSATA port. You won't fit 4x 3.5" HDDs unless you get some SATA 22 pin extender cables.
IMPORTANT: the RADXA Penta SATA Hat guide warns to not plug in both the USB-C power adapter and the 12V barrel jack power adapter at the same time!
Another reason for choosing the RPi5 is that you can custom 3D print an enclosure to your liking for optimal thermal performance and to protect your rig. I haven't printed a case yet, but there are multiple models available online to tweak. This design https://makerworld.com/en/models/895460-radxa-penta-sata-hat-nas-enclosure#profileId-853279 leverages an active cooling solution and looks the best in my opinion. If I were to print an enclosure, I would add two 40x20mm Noctua fans since they have a high reputation in the PC building community for being quiet (and expensive!) (https://a.co/d/2qaENCV).
Here are a few other cases that I think are good:
For the Raspberry Pi, I installed Raspbian on the microSD card, and setup my wifi credentials and my SSH key. Nothing fancy.
Thankfully, this step was easily done. Just a few CLI commands to run. More details in the build guide!
Not being new to the home server community, I had already tried TrueNAS https://www.ianwebster.ca/post/truenas-home-server and NextCloudPi https://www.ianwebster.ca/post/nextcloudpi for self-hosting. I chose to avoid NextCloudPi since I wanted to explore containerization. Unfortunately, TrueNAS is not compatible with arm64, so that means I was left with OMV for the RPi5.
While OMV (OpenMediaVault) does not have my favourite UI or configuration experience, it gets the job done.
I'll go more into depth setting up OMV in my build guide!
Before considering setting up Tailscale, I needed to answer the question: "how will I store files on my server in confidence that they won't succumb to bitrot?" TrueNAS would have me covered if I had chosen x86 since TrueNAS natively uses ZFS. Unfortunately, I chose arm64, so I needed to find another way to install ZFS. Fortunately, there is an OMV plugin for ZFS! Saved.
I wanted to be able to containerize different services to encapsulate the different use cases I wanted to try out on my server. For example, I wanted to try out NextCloud (file sharing) and Immich (photo sharing). Docker is the best way to isolate these services. I tried out NextCloud first since I found a decent guide to set it up with Tailscale.
One of the motivations I noted earlier for this project is the fact that a couple friends of mine both brought up Tailscale within the same month. I became curious. I saw that Tailscale could be used to remotely access home servers from clients like your phone and PC. It was even more intriguing when I discovered Tailscale's Funnel feature that allows you to open your services to the open internet!
I found this guide https://github.com/nextcloud/all-in-one/discussions/5439 which considers the setup of NextCloud using Tailscale as a reverse proxy, using Caddy as a sidecar for TLS termination of HTTPS.
I modified the docker compose file to inline the Caddyfile and Caddy.Dockerfile such that I could load a single compose file into the Docker UI in OMV. If you're not a fan of the UI, you can always SSH into the pi and run via the CLI. I found it easier to use the Docker CLI for development.
I realized I could set up Tailscale's Funnel feature (in beta at the time of writing this) to open traffic beyond my Tailent. As a result, I could connect to my NextCloud server from my phone without being on my local network or connected to my Tailnet.
I got NextCloud Talk (text and video conferencing) working over my Tailnet, but I could not forward the ports to be accessible via Funnel. It's possible the GitHub thread has more updated guidance on these ports, but at the moment, I believe it's not possible to forward them using Tailscale Funnel acting as a reverse proxy - you can only forward HTTP (port 80) and HTTPS (port 443) traffic.
Not being 100% satisfied with NextCloud's native photo organization and sharing capability, I naturally stumbled upon Immich. Immich looks almost identical to Google Photos, and is entirely self-hosted! I created my own docker compose file based on the NextCloud + Tailscale + Caddy configuration, which I got up and running in less than a couple days. I was sharing photos and videos with friends and family in no time.
Thank you for checking out this post! I will be writing a build guide soon.