Setting Up Home Web Servers, Part 01 — Thu 17 July 2025

Setting Up Home Web Servers, Part 01

Right now, I have a single web server running at home, my instance of Sandstorm. So in my internet router, I have port 443/HTTPS forwarded to my web server.

It's funny how gaps in knowledge you didn't realize that you had hit you. It wasn't until last year that I learned of SNI. I had thought that if I wanted to run 5 websites all on port 443, I needed 5 IP addresses. SNI lets a single IP address serve an essentially unlimited of websites on port 443 (or any other port, for that matter).

As I mentioned in another blog post, I want to work on my fork of Tempest, Ian Denhardt's planned successor to Sandstorm. Tempest includes the ability already to replace an existing Sandstorm instance.

But I don't want to replace my existing Sandstorm instance with Tempest while Tempest is a work-in-progress. And presumably, I will be testing the migration to Tempest from Sandstorm multiple times. So I need at least three websites: existing (production) Sandstorm, test Sandstorm for migrations, and Tempest.

Without SNI, the new test Sandstorm instance and Tempest instance would require renting two virtual servers with public IP addresses somewhere, or something like that. With SNI, if I can set up a reverse proxy properly I can run it all from the same single server.

Popular reverse proxy choices include Apache, nginx, and HAProxy. I use HAProxy at work, and I'm familiar with it and it has been bulletproof for my employer. But for this project, since Tempest is written in the Go, I figure I'll try a reverse proxy written in Go. So, Caddy.

But before I can use my reverse proxy, I need the SSL certificates from my Sandstorm implementation extracted and available to it.

I'm going to run my reverse proxy in a virtual machine running Guix.

I've done this:

  1. Added an SSH public key to my Guix machine definition: https://git.sr.ht/~mikeswierczek/guix-configs/commit/9a7ed6171c93d06e8deeca409cbcb24d779d5dac (and rebuilt my Guix machine)

  2. Started the Guix machine, with local port 10022 mapped to ssh port 2222 on it. Then I logged in over ssh as the guixadmin user, and created the directory /home/guixadmin/certs with mkdir certs.

  3. On my host machine, added the corresponding private key under /root/.ssh/guix/ and the following shell script at /etc/cron.daily/sandstorm-certs:

#!/usr/bin/env bash

main() {

CERTDATA=`echo 'db.settings.findOne({_id: "tlsKeys"})' | /opt/sandstorm/sandstorm mongo`

echo $CERTDATA | sed "s/^MongoDB.*key\" : \"\([^\"]*\)\".*/\1/" | sed "s/\\\n/\\n/g" > /root/certs/sandstorm.key
echo $CERTDATA | sed "s/^MongoDB.*certChain\" : \"\([^\"]*\)\".*/\1/" | sed "s/\\\n\\\n/\\n/g" | sed "s/\\\n/\\n/g" > /root/certs/sandstorm.pem

scp -i /root/.ssh/guix/id_ed25519 -P 10022 /root/certs/sandstorm.key guixadmin@127.0.0.1:/home/guixadmin/certs/
scp -i /root/.ssh/guix/id_ed25519 -P 10022 /root/certs/sandstorm.pem guixadmin@127.0.0.1:/home/guixadmin/certs/
}

main "$@"

I tested it, and now I have my certs in my Guix VM.

For future work in Guix, rather than rebuild the VM I'm going to work as a normal user.

Up next: installing Caddy in my Guix VM, changing my Sandstorm installation to use Caddy, and setting up Caddy to use the Sandstorm certs and reverse proxy for Sandstorm.