Server setup

Running services

I'm running the following HTTP-based web services on my server:

Additionally, I'm running a mail server via Postfix and Dovecot, and an ad-blocking DNS server (Pi-hole). As the firewall, I'm using ufw – though note that there's another firewall on the router.

Service setups

Caddy, apache2, ufw, postfix, and dovecot run directly on the machine, installed as system packages. The rest runs as podman containers, via a bunch of podman-compose.yml files that expose the services' plain-text HTTP interfaces on some port only to localhost, e.g. 127.0.0.1:9000. Adding new web services is just a matter of spinning up new containers and telling caddy to reverse-proxy incoming traffic for some subdomain to their HTTP port. Scheduling a crontab (1) job to update the container images periodically (e.g. weekly) might also be a good idea.

Lingering users

In case the system uses systemd-logind for managing login sessions, systemd will kill all of a user's processes (via a per-user scope unit) when they log out. This obviously interferes with some utilities that are meant to outlast a login session, like tmux or podman containers. Luckily, there's a way out by telling systemd-logind to start a user manager for individual users at boot that is kept around after logouts: loginctl enable-linger ${username}

Punching pi-holes

To allow pi-hole to act as a DNS server, I had to stop systemd-resolved from listening to port 53 by setting DNSStubListener=no in /etc/systemd/resolved.conf.

Custom ufw rules

Because podman typically runs as an unprivileged user, using port 53 (which is pretty much required for DNS servers) is out of the question by default. Instead, I've added an iptables redirect via the ufw config – similar to the approach from this blog post. On my server, I added a few lines to the top of /etc/ufw/before.rules, under the "*nat" section:

# redirect port 53 to 5353 (pi-hole)
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 53 -j REDIRECT --to-port 5353
-A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 5353
COMMIT

To be on the safe side, I also allowed the port: sudo ufw allow 5353

Extra virgin snakeoil

I've symlinked /etc/ssl/{certs,private} and /etc/dovecot/private, pointing to ~caddy/.local/share/certificates/.../max-moser.dev/..., to give postfix and dovecot access to actually valid certs instead of self-signed snakeoil certificates. Give Google Mail & co one reason less to junk-jail your emails.

Some fresh software

Debian and Ubuntu aren't exactly known to be bleeding edge distributions; it's quite common that the versions of packages are a bit dated (if they're available at all). Neither jless nor yazi are available, and the version of rust is too old to compile them from source. Luckily, this can be sidestepped by installing rustup with apt and using that to install the latest version of rust, which in turn can be used to easily cargo install the desired commands.

Editing files on the server

I've found that editing files on the server with good old vim can be a bit of a slog, I actually miss the LSP integration from my nvim setup! Fortunately, sshfs (1) exists and can solve this exact problem. Mounting the server's file system to a local directory server-mount is as simple as this command: sshfs -o follow_symlinks user@server: ./server-mount