Homeserver Management with Linux and Puppet

During the Covid-19 pandemic I decided to set up a server at home for different use cases. The server, that I very creatively called server1, should be a central place to build a file archive, a git server (an alternative for GitHub projects not intended for the web), a testing server for new applications (such as Keestash) and other stuff. Further, server1 ist only intended to stay in the local intranet (not reachable from the web) and does not underly strict security constraints. Let’s talk about server1, the setup and especially configuration.

The hardware

As I said, one of the primary use cases for server1 is a web based file archive. Therefore, it is necessary to have a powerful computer with an external hard drives as a RAID.

Minis Forum Personal Computer
Minis Forum Personal Computer and ICY Box RAID Case

The Minis Forum PC is shipped with an Intel Quad Core CPU, 4 GB RAM and 64 internal memory and pre installed Windows 10. The ICY Box case holds two 4GB Seagate HDD’s and serves as a RAID. You can find them on Amazon here, here and here.

ICY Box RAID Configuration

For those who do not know what a RAID is, Wikipedia describes it as:

RAID (“Redundant Array of Inexpensive Disks” or “Redundant Array of Independent Disks“) is a data storage virtualization technology that combines multiple physical disk drive components into one or more logical units for the purposes of data redundancy, performance improvement, or both.

Wikipedia description for RAID

Since I want to use the hard drive of the ICY Box mainly for archiving files and pictures, it is definitely useful to utilize a RAID for backup and data redundancy. There are a few hardware buttons to click for enabling the RAID mode. Please check the manual shipped with the Box and do not forget to format the hard drives with the appropriate file system (ext4 in my case).

Minis Forum PC Configuration

As I want to run a linux server on the PC, it is first necessary to format the hard drive and install Linux. I decided to use Debian as the operating system since it is the mostly used OS for servers and has a lot of packages/software to use.

To install Debian, we first need to create an bootable medium (e.g. USB memory stick). Debian images are available on the official Debian website’s download section and using UNetbootin, we can easily create a bootable medium to install Debian.

The Debian installation is very straightforward, except the network drivers for WiFi. Since they are not installed with the operating system, it is necessary to install them manually. There are mainly two steps to take into account, to install them. I described them here under “Linux Related Issues” and also uploaded the necessary text file here.

Debian Software and Service Management

So far, we enabled the RAID mode, formatted the hard drives in our ICY Box and installed Debian on the Minis Forum PC. The PC is connected to our local network (LAN or WiFi) and we have SSH access to the server from our laptop.

At this point, we could start to install all necessary software and services manually. For my case, I need the following software/services on my server:

  • Apache: a webserver to host and test “internal” applications
  • GIT: for software versioning, needed for Gogs
  • PHP: to testing applications on “real” Linux hardware
  • ownCloud: to have a web based file storage
  • MySQL: a DBMS for the applications mentioned above
  • Gogs: GitHub like git service to host private repositories

Further, some of the software packages mentioned above need extensions (such as curl for PHP), the ICY Box has to be mounted properly, the operating system users are available and have sufficient permissions and all files and folders, required to run software/services mentioned above are there and have the appropriate permissions.

It is obvious that configuration becomes much more complex and time consuming as the list of required software and services grows. Further, we need fallbacks and make a lot of security checks (for instance, checking file/folder and permission presence) in order to have a running system. It is clearly obvious that we need a way to automate these steps.

Puppet Apply

Puppet is a straightforward way to automate server configuration for installing and managing software as described above. There are two main modes in which you can run puppet: Master-Agent and Apply. In Master-Agent mode, the master holds and compiles the “puppet receipt”. Each agent requests periodically the receipt from the master and applies it, if there is any difference to the current state. The apply mode is a single server infrastructure, meaning that the server holds and compiles the receipt for itself. There is no outbound reporting to other machines by default. Puppet Apply acts like a standalone combination of Master-Agent.

Since I run a single server only, I am using Apply for my home server.

In Puppet context, we are talking about manifests when we want to configure our server. Configuration steps are defined in one or more manifest files which are then compiled to a single manifest and applied by puppet.

The use case I have – installing and managing software, services, users and files/directories – enables me to create a single manifest file. When the manifest is growing in future, it is possible to split it into logically separated manifests.
Further, if one or a collection of manifests solve a specific problem, it is possible to turn them into a puppet module and make it available for others.

Talking About Puppet Modules

Common problems are usually solved by others and are usuable by puppet as a module. For my use case, there are modules for apache, git, php and mysql. For instance, if you want to install the puppetlabs/apache module, you can simply run the following command: puppet module install puppetlabs-apache –version x.y.z

Puppet Receipt

Let’s talk about my puppet receipt. As mentioned above, I decided to create a single receipt file, mostly because there are common packages to install and I used it for a “learning by doing” process. Therefore, when talking about the receipt and commands, I am referring to a single file site.pp.

I strongly believe in object oriented programming and value advantages of classes and objects. I am aware of that server configuration with puppet is not comparable with OO, but still: I decided to utilise classes and want to see what advantages and possibilities they provide. Therefore, my whole configuration remains in a single init class. Depending on how configurable Puppet is in its nature, I want later split everything logical structured classes (once the receipt starts growing). But let’s have a look into the init class in site.pp:

Explanations

The first three package commands manage packages from the official OS repositories (apt in this case). We are ensuring that curl, openssh-server and ca-certificates are installed on the system.

Next, we are using a class called ‘apache’ and located in another module. Notice that we do “only” care about how apache is configured, the most work however is done under the hood by the module.

The apache::vhost resource is interesting: As I mentioned earlier, I want to run a web based file storage. Therefore, I need to configure apache vhost and define some values (the incoming port, document root, webserver user, etc).

Next, we are configuring PHP. We need to enable the PHP module for apache which is done on line 33. From line 41 to 89, we ensuring that PHP is installed in version 7.1 together with some extensions.

Lines 96-125 install and configure MySQL and 126-143 create and monitor database users and schemas together with credentials and permissions.

Line 151 is interesting as it ensures a mount: As described above, we are using a RAID for file storage. mount ensures that the RAID is mounted properly and the file commands in 158, 164 and 170 ensure that the corresponding directories exist.

Lastly, we create an Linux user which is needed by Gogs and call our init class on line 185.

Notice that modules for packages such as owncloud or gogs are not available/in a beta state and are therefore unfortunately istalled manually.

IMPORTANT: As mentioned in the beginning, this server remains in my local network and is never accessible from the internet. Therefore, I did not care about secure communication and encryption (such as SSL/TLS). Please keep this in your mind while configuring your server – especially if your server is intended for the public web.

Once the receipt is ready, the installation on the server is very straightforward. We need to store the file on the server and run the following command:

Applying a Puppet Receipt

Conclusion

In short: it work’s once the receipt is written properly. While dealing with puppet, I noticed that there is not as much experience as with other technologies (for example, typing “puppet” into StackOverflow has about 11,000 unanswered questions where as JavaScript results in 582,000 unanswered questions). Therefore, you have to make a deeper look into things when having a problem and want to solve it. Try to make notes as the solutions found will not be the first entry in the Google search and blog about it to make it available for others 🙂