The Raspberry Pi Cluster
HardwareI recently got a Raspberry Pi 4 as a birthday gift, which bumps the number of Raspberry Pis I own up to 3 now. It’s been bugging me to just have Raspberry Pis sitting around doing nothing, especially knowing that the demand for them is so high right now. So I wanted to play around with building a cluster.
Physical Mount
The first order of business is to actually put these somewhere physically. I looked briefly on the internet to see if there were any good cases or what not to mount my three Raspberry Pis in, but I didn’t find any that I really liked. They ranged from €20 for a really simple stacked plastic mount to over €100 for fancy metal cases. But I also had another problem, my very first Raspberry Pi doesn’t have any mounting holes! And I can’t just not include my very first Raspberry Pi in the cluster. Especially since Raspberry Pis are going for around €200 nowadays. So I went to the hardware store and bought a couple cheap wooden boards for a euro each.
I placed the Raspberry Pis in this arrangement so I could easily plug the power supplies in, and have the ethernet ports face the switch.
Then I drilled holes through just the one board so they’d be a consistent depth, glued the boards together, and forgot I had only two clamps.
For the Raspberry Pi 1 I looked online to see if there was a decent mounting solution. And I saw these side mounts for just €3, hell yeah!
Hmmm, nah.
So instead I just put a few extra holes and mounting holes where they looked like they would fit. And then I put some extra plastic washers between the copper mount and screw. And it works decently.
The nice thing about this is it really didn’t cost that much, so if I don't like it I just can scrap it. And I didn’t glue in the risers so I can reuse those too.
Operating Systems
I flashed my Raspberry Pi 3 and 4 with 64 bit Raspberry Pi OS, and I flashed the Raspberry Pi 1 with 32 bit Rapsberry Pi OS. Then I used an Ansible playbook to install docker on all of the Pis and create a Docker swarm, with the Raspberry Pi 4 as the manager, and the two others as workers.
I would have liked to have a UI to manage the applications that I want to deploy. I tried out Swarmpit, but it won’t run on the Raspberry Pi 1, which kinda sucks but it doesn’t matter too much to me. I'll just ssh into the manager node, and deploy my applications from there instead.
Domain Name System (DNS)
Next I installed Nginx proxy manager to have domain names in my household. I’m annoyed to find out that it’s discouraged to the top level domain (TLD) .local, because of multicast DNS and other applications that use that particular TLD. Apparently the following domains are recognized private DNS namespaces:
- .intranet
- .internal
- .private
- .corp
- .home
-
.lan
But the only one of those that actually attempts an http request automatically in Firefox instead of doing an internet search is .internal.
I don’t want to have to type http:// every time I want to open one of my home applications. So I’m just going to use .internal for my home network. I’ll also mention that .home.arpa is available to use for private use, but that’s a rather lame TLD to use in my opinion.
I also saw recommendations to actually buy a public domain so that it’s definitely reserved, but I don’t really want to tack on future spending for this silly project. It might be worth considering some day if I really want to generate certificates, so I can use Let’s Encrypt as my certificate authority. But that’ll be something for another day.
Applications
The first order of business is to have a reverse proxy, so that I can forward web requests from port 80 to other applications. So I’m using Nginx Reverse Proxy for that.
I also don’t want to have to insert domain names into every hosts file on every computer that I use, so I looked around for a simple DNS manager that I could install on one of my Raspberry Pis. I found that the easiest to use is PiHole, so I set that up on my cluster and also set it up with my router.
Next I installed FileRun. A simple FileManager
After uploading my music and some videos, I realized I wanted a more elegant way to view my videos. So I got JellyFin up and running too.
It's nice having both FileRun and Jellyfin since Jellyfin doesn't have a way to upload media. So I just share a volume between the Jellyfin container and the FileRun container, and then have a Jellyfin user in FileRun to upload media.
After playing around in the JellyFin settings I saw that there was a setting for live TV. There I saw that there was a plugin for Tvheadend, a TV streaming server for Linux. And with Tvheadend you can use a DVB-T (Digital Video Broadcasting – Terrestrial) tuner to receive television. I happen to have a cheap tuner that I bought for less that $10 laying around. I’ve used it for software defined radio mostly, but now I can actually use it for it’s intended purpose. So to test, I fired up Tvheadend in a Docker container on my desktop, and got one lame channel:
Turns out Germany, moved from DVB-T to DVB-T2 a few years ago. But I really want to try to get decent TV on this cluster now, so I ordered a DVB-T2 tuner. Specifically a DVB-T230.
Once I got it, I downloaded the firmware for it on Linux (specifically dvb-demod-si2168-d60-01.fw and dvb-tuner-si2141-a10-01.fw from here if you want to use the same tuner), tested it out, and got way more channels as expected. So then I put the firmware on my Raspberry Pi 3, plugged in the tuner, and went to set it up in my Docker Swarm. But I found a problem with the stack.
Unfortunately Docker Swarm doesn’t support device pass throughs. Running a regular docker container supports passing through a device, but in swarm mode it has yet to be implemented.
So I took my Raspberry Pi 3 out of the swarm and just deployed the Tvheadend container as a regular docker-compose file. Then integrated it in Jellyfin with the Tvheadend plugin. I got 36 unencrypted TV channels, but they were very choppy. I checked dmesg and as I expected it was complaining about my cheap Amazon power supply.
So I got an official Raspberry Pi power supply for it, and it stopped complaining about the power, but the channels were still choppy. The next thing I looked at was the antenna. This thing is tiny, and my apartment has very thick walls.
I first tried plugging the T230 into the antenna outlet in my wall. But Tvheadend didn’t find any channels. Conveniently though, the T230 can also receive channels through regular cable as well as over the air. So with an antenna to coaxial f connector adapter, I plugged the T230 into the cable socket, and it picked up 96 channels! And even some channels in English such as BBC, CNN, and CNBC!
Now I can enjoy the best TV that Germany has to offer, such as RTL.
HDTV channels are still somewhat choppy through Jellyfin. I checked htop on my Raspberry Pi 4, the Pi with Jellyfin, and the CPU is topping out when I attempt to watch those channels. I’m not sure what to try next. I did end up putting a heatsink on the CPU as it was incredibly hot to the touch. That helped a little bit I think. But still the Raspberry Pi seems to be a little underpowered for the job. I’ll just have to keep playing around with it.
Wrapping Up
So the last thing I have to do is to cut the board down and put it in place.
Damn I wish I had a bigger saw right now.
Now to put in the shelf, out of the way. With the best cable management that I felt like doing.
So it's not truly a cluster, due to the limitations of Docker Swarm and what I ended up wanting to do. Maybe I could look into Kubernetes, seems like it'd be overkill for such a silly home setup. But this will do for now.