The case of the server-laptop hybrid

I'm slowly reaching the limits on my Raspberry Pi 3, and need something with better hardware to do stuff with.

This is where my laptop comes in. It's got good specs (even plays games) and I rarely need to use it. Almost perfect. There is only one roadblock left:

What if I need to use it as a laptop?

Some thinking later, I got the solution: What if the laptop became a server only when it's not being used? That would work, wouldn't it?

I mean, I am the only person actually needing anything I'm hosting (aside from the Pi-hole), so it wouldn't matter at all if it wasn't running 24/7.

So let's get to work.

Preparing the laptop

Since the laptop will be a server, it should be as light as possible, while still being usable as a laptop. So we'll need something with a small amount of initial background services, since we can start the rest when we need to.

I am choosing Artix Linux with Runit for this project, partly because of my familiarity with the Arch base, partly because of how fast Runit boots, and partly becasue I already have an ISO of it.

I know, rolling releases are bad for servers, but so is adding random PPAs to get up-to-date software.

So anyway, initial install is successful, with a very light idle system (~150 MB RAM used, little to no CPU usage)

Server setup

Since I was already planning to run everything inside Docker containers, the Docker daemon sounded like a great way to seperate the server side and the laptop side.

So, the thing we need to do, is to run the Docker daemon when we need to be the server. But how do we decide to become the server?

Since my home network is behind a static IP with no CGNAT or anything, I can simply check for my public IP, and run the Docker daemon when that public IP matches my home IP.

So, if you'll excuse my horrible scripting, here is how I managed to do just that:

#!/bin/sh

sv start NetworkManager || exit 1

TRIES=1
while ! ping -c 1 -W 1 1.1.1.1; do
        echo "hybrid: Waiting for network... (try $TRIES)"

        sleep 5
        TRIES=$(($TRIES + 1))

        if [ "$TRIES" -gt 5 ]; then
                echo "hybrid: No network connection could be made."
                while true; do
                        sleep infinity
                done
        fi
done

MYIP="$(dig @resolver1.opendns.com ANY myip.opendns.com +short)"

if [ "$MYIP" = "x.x.x.x" ]; then
        echo "hybrid: Home network detected, running as server"
        sv up docker
        sv up dropbear
else
        echo "hybrid: Server mode disabled"
fi

while true; do
        sleep infinity
done

Also, I ran sudo touch /etc/runit/sv/docker/down for both Docker and Dropbear just so they wouldn't start on boot, but instead get started from my script.

And the good thing about runit (or maybe just Artix's configuration of it) is that these services do not block the login screen, so I can log in while waiting for the script when I don't need it.

Anyway, that's the server side done. Now, I can just add anything I want as a Docker container, and have it automatically start only if I'm at home.

Also, don't forget to disable the lid suspend, so you can keep the lid closed while the server keeps running.

User setup

Now that the server part is done, all I need is the laptop part, and we're done.

For that, I'm planning to use the LXQt desktop environment, as it's light, and gets the job done.

There isn't much to write here, as the laptop will be on "user mode" unless needed, so there isn't any special case needs for this. Just install a DE or a WM, configure it to your liking, and you're done.

The end

And with that, we're done. I'm going to stick my laptop somewhere out of sight, and use it as a server, until I need to go somewhere, in which case I'll get it with me, and just run startx whenever I need it. Simple!