First Project With A Raspberry Pi
For some time, I have been wanting to replace my self-built router with a Unifi Gateway so that I could build a Docker server out of that system. Unfortunately, the Unifi Gateway continues to lack a feature I need: monthly bandwith usage tracking. Until it at least gains that feature, I will be sticking with pfSense. But there are at least two things that I really need a Docker server for:
- Running the Unifi management app via https://github.com/jacobalberty/unifi-docker
- Running a localtunnel server
As I was mulling over this problem, it occurred to me that these use cases do not require tremendous resources. So I decided to make my first project with a Raspberry Pi be a project to turn one into a Docker server. This post details my experience and setup, because it hasn’t been easy.
- RPI 4 B (8GB)
- 64GB Memory Card
- HDMI to micro-HDMI adapter
- Power cable
- HDMI to micro-HDMI cable
- PoE Hat
- Vesa Mount
Not all parts in this list were useful. Keep reading for details.
I naively thought this would be a simple project: buy a Pi, slap an OS on it, install my stuff, and done. Not so. After getting all of my initial parts together, I went to plug everything in and get started. Oops. The RPI4 is powered via USB-C, not micro-USB-B. So the power cable I bought turned out to be useless and I had to return it. Resolution: power the RPI4 via a USB-C cable connected to my laptop.
Now that the device is getting power, I discover my second problem: no display.
I tried updating the
config.txt several times to get the display
working. Nothing helped. So I ordered a direct HDMI-to-micro-HDMI cable and
put the project aside for a couple of days. After getting the cable, plugging
it in, and powering on the RPI: boom! I had a boot screen.
Post Boot Issues
Now that I had a booting RPI4, I started configuring it. I used the
raspi-config tool to set all of my basic settings and rebooted
the system to find that it would not connect to my wireless network. Everything
looked correct, but since the official RPI OS is based upon Debian, everything
was obscurred by systemd. I did some basic log inspection, but couldn’t find
any relevant error messages. So I decided to check if Void Linux would
work. Turns out, not quite.
Void, at this time, only has pre-built images for the Raspberries 1, 2, and 3. They do not have an image for the RPI4. However, someone had figured out how to build such an image. So I started working on that.
Building A Void Linux Image
The patch and instructions for building the image are at: https://github.com/void-linux/void-packages/pull/23541
Unfortunately, Void moves fast and those instructions resulted in merge conflicts. So here’s my tweaked instructions:
- Directly clone the
- Directly clone the
- Create a new branch in the
- Apply the Pull Request’s changes manually since they are few.
- Follow the rest of the instructions as printed.
I recommend doing all of this in a virtual machine with a fresh install of Void Linux as the working environment. It is going to take a long time to complete all of this. There will be several cross compliation and build stages.
After building the image and flashing it to the memory card, I mounted the
/boot FAT32 partition and replaced the
config.txt with the one from the
Void Is Live!
The Void based card booted (and a helluva log quicker than that systemd based
nonsense, too), I edited
/etc/wpa_supplicant/wpa_supplicant.conf to add my
network configuration, enabled the
wpa_supplicant service, and I immediately
had a working wireless connection. Success!
First things first, resize the root partition:
resizepart 2 62GB
Next, try to install Docker… Sadness! A pre-built package is not availble: https://github.com/void-linux/void-packages/issues/18062.
At this point, the system was usable, but due to lack of community support, some work had to be done to get everything where I wanted it. Mostly, this just meant setting up a build environment on the Pi so that I could build the Docker packages. After that, it was all normal system setup. What this meant for me, was getting the ethernet NIC configured for the IP address I wanted to give it and then mounting it in its permanent location. That way I could do the remainder of the work headless over SSH.