~$ Building a Raspberry Pi private web server!

Posted on May 4th, 2022. | Est. reading time: 5 minutes

Tags:DevelopmentCyber SecurityDevOps

I was recently asked whether I could a family member out, as they needed a custom inventory management platform for pieces of a family art collection.

I accepted, although I probably shouldn't have.

I'll go over how the project services were designed, how it is being hosted, and more, in this blog post.


The service architecture

The project follows a pretty simple design: the web frontend is how the user interacts with the service, the backend is how the service saves the data to a database.

Due to my past experience, I decided to write the frontend in Angular, and the backend in Python, using FastAPI as the middleware. The database would use MySQL.

The Pi

For a myriad of reasons, we decided to use a local system, and decided to do so on a Raspberry Pi 4.

The Pi has a number of advantages, but the one I retained was that one could have it boot off of an SSD, rather than the traditional SD card.

Another neat thing is that there are a lot of case designs to 3D print, and I found a design that allows for an SSD, and additional ventilation fans.

I got my model for the casing from Thingiverse, which I then printed at the FacLab, my university's makerspace.

The first element was to fit the SSD into the casing. In order to have it snug against the base, I flipped it from its original configuration.

The base casing with the SSDThe base casing with the SSD

This meant that, in order to have the Pi itself fit snugly in the casing, a strut of sorts was needed. I designed it by using the RasPi design sheet.

The RaspberryPi strutThe RaspberryPi strut

The Raspberry Pi then aligned perfectly with the holes in the casing, letting me start with the ventilation, which consists of a CPU heatsink/ventilator unit, and a casing 40mm ventilator.

The fitted RaspberryPiThe fitted RaspberryPi
The RaspberryPi with the ventilationThe RaspberryPi with the ventilation

The final device, bar some cables, looks like this:

The completed RaspberryPiThe completed RaspberryPi

What does it run?

From the get go I decided that I would use containerized applications, probably using Docker.

This somewhat restricted my choice of platforms, so I went with a very lightweight and headless version of Ubuntu, which I flashed onto the SSD.

I then installed containerd, docker and docker-compose for the management of our services, and went on to design a service architecture.

I knew I would need a frontend (for the user to perform the relevant inventory actions), a backend (to handle said actions) and a database (to store the data).

I also knew I did not want to use PHP, despite the fact that it would cut out the backend portion, because it isn't that great for modular code blocks, whereas Angular (when done right) is fantastic.

The backend I decided could be done in FastAPI, mainly because it supports being run in a service-esque fashion via uvicorn, and I didn't need inordinate speed.

As for the database, although I'd originally started by using a NoSQL database (MongoDB), I reverted to MySQL when I realized that searching specific fields could be made quicker with indexed data.

This led the final services architecture to look something like this:

The services architectureThe services architecture

After all of this was setup, I configured a few services such as a backup system, which exports the database to the device and uploads it to a server I control, and a firewall, which disallows anyone not connected locally on the network from accessing the services, whether web or SSH.

Finally, I setup a cron job to allow the device to restart the various containers on reboot, which gives my relatives the ability to move it and work on it wherever they are, without the hassle of "needing an engineer". I can also SSH into it to apply an update when I see them (or remote into their computer to do it), which helps!