Deploying my Gemlog

After first exploring gemini _years_ ago by way of tilde.team, I've finally gotten around to setting up my own self-hosted agate server. Every time I look into gemini I'm taken by the simplicity conciseness of the setup. My other infrastructure seems to demand so much more in comparison, whereas with my gemlog I've managed to setup an extremely simple interface on day 1 that I won't ever have to stop and re-learn to deal with. Lets take a look at a refreshingly simple approach to automatic deployment!

Prerequisites

The only real prereq here is that your gemlog or capsule is hosted on a server that you have ssh access to, which is going to be pretty much anyone writing a capsule, including those hosting through tildes. If you have ssh access, you can be pretty sure you also can use sftp and scp, which we'll be using here.

Makefile

I decided to handle this through a makefile since it's a familiar way to handle basic commands in a repo, but this could just as easily be a shell script. I wanted to make sure I had a dead simple way to deploy if there was ever an outage or problem with SourceHut's build system. Here are the contents of my makefile:

push:
        scp -r . agate@dumpnet.chat:/var/lib/agate

One line and we have our project synced. dumpnet.chat is a domain I own and host a few services on, but you can use whatever server you have access to. `make push` should work right out of the gate if you're working from a computer that already has its ssh key shared with the server. SourceHut has some built-in functionality for handling ssh keys, so make sure you mark the secret as an ssh key when given the option.

Speaking of which, we'll have to generate a key for the SourceHut build to use next.

Setting up the SourceHut Keys

First, generate an SSH key to use just for SourceHut builds:

ssh-keygen -t ed25519 -C "sourcehut-deploy" -f sourcehut-deploy-key

In SourceHut, go to builds > manage secrets > add new secret. Name it whatever you want, it's not particularly important. Save the secret key (which will be the one that doesn't end in .pub) as the value of the secret.

Next, you'll have to put the public key on your server. You should have a `~/.ssh/authorized_keys` folder, and you'll have to append the public key file's contents to that file. Don't delete anything that was already in there.

Setting up the build manifest

Next, create a .build.yml file in the root directory of your git repo. This is what will be run whenever you push to the repo. Here's mine:

image: alpine/edge
packages:
  - make
  - openssh
secrets:
  - a6ebcbf6-ee6e-4e0f-8d1c-104867bb2370
tasks:
  - deploy: |
      ssh-keyscan dumpnet.chat >> ~/.ssh/known_hosts
      cd gemlog && make push

You'll be able to get the secret ID from the sr.ht builds / manage-secrets page for the secret you created earlier. The keyscan step was necessary for me to get around the typical 'this is an unrecognized ssh host, do you want to trust it?' ssh dialog.

And that's it, the cleanest and easiest deployment pipeline I've ever set up. Now whenever you push to the repo housing your gemlog, it will update your capsule automatically. You don't even have to be working from a computer with access to the server!