💾 Archived View for zozoandsqueak.ca › articles › tech › running-zozoandsqueak.gmi captured on 2023-04-26 at 12:50:25. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2022-06-03)
-=-=-=-=-=-=-
my lab is split between a pair of proxmox [1] nodes that run at home and a single proxmox node running on a bare metal server i picked up on sale from ovh [2] a while back. a wireguard vm running in each location provides a private link between the two sites. most of the services running in the environment have been virtualized as either full virtual machines or through lxc containers, but a number of smaller services (including the gemini server) are running on the ovh node in a /miscdocker/ vm, which has typically been used for things that require very little resources (like gemini) or things that i'm just trying out and may migrate to a dedicated environment at a later date (like the grocy server i keep thinking will be a good idea, but never can quite get around to using). one of the proxmox nodes at home runs a virtualized k8s cluster that typically becomes the new home for dockerized apps that are no longer suitable for /misdocker/.
miscdocker is not directly exposed to the internet, so traffic ingresses through an haproxy instance setup to forward tcp traffic on port 1965.
the frontend:
frontend gemini_in mode tcp option tcplog bind :1965 use_backend tcp_gemini_1965
the backend:
backend tcp_gemini_1965 mode tcp server gemini miscdocker.chickenoncow.cloud:1965 inter 1000 check
zozoandsqueak is using the dockerized version of the gemini server [3].
the command i'm using to start the server is slightly modified from the example provided on the github page:
docker run \ -d \ --restart=always \ -v /etc/letsencrypt/live/zozoandsqueak.ca/:/certs \ -e PORT=1965 \ -e DOMAIN=zozoandsqueak.ca \ -v /opt/zozoandsqueak/:/content \ -p 1965:1965 \ adrianhesketh/gemini:latest
you'll notice from the docker command that the certs are being generated by letsencrypt. i'm using dnsmadeeasy [4] to host DNS for zozoandsqueak.ca and they have an api that works with certbot for automated verification which is nice.
to generate the certificates, another docker container is being utilized, this one is created using an image that comes pre-populated with certbot and the dnsmadeeasy plugin.
docker run \ --rm \ -it \ --name certbot-dnsmadeeasy \ -v /etc/letsencrypt/dnsmadeeasy.ini:/dnsmadeeasy.ini \ -v /etc/letsencrypt:/etc/letsencrypt \ certbot/dns-dnsmadeeasy \ certonly \ --dns-dnsmadeeasy \ --dns-dnsmadeeasy-credentials /dnsmadeeasy.ini \ -d zozoandsqueak.ca
this generates a set of pem encoded files on the host
├── zozoandsqueak.ca │ ├── README │ ├── cert.pem -> ../../archive/zozoandsqueak.ca/cert1.pem │ ├── chain.pem -> ../../archive/zozoandsqueak.ca/chain1.pem │ ├── fullchain.pem -> ../../archive/zozoandsqueak.ca/fullchain1.pem │ ├── privkey.pem -> ../../archive/zozoandsqueak.ca/privkey1.pem
the gemini server is expecting the key and certificate to be in the /server.key/ and /server.crt/ files respectively, so a quick and dirty script to be called as a post hook by cert bot when the certs renew takes care of that.
#!/usr/bin/env bash DOMAIN=$1 if [[ -z ${DOMAIN} ]]; then echo "usage: rebuild_certs DOMAIN" exit 1 fi cd /etc/letsencrypt/live/${DOMAIN} rm -f server.{key,crt} cp cert.pem server.crt cp privkey.pem server.key
this gets mounted into the docker container from /miscdocker/ along with the letsencrypt and dnsmadeeasy config volumes into a script that will be called from a daily cron job
root@miscdocker:~# cat /usr/local/bin/renew_certs #!/usr/bin/env bash docker run \ --rm \ -it \ --name certbot-dnsmadeeasy \ -v /etc/letsencrypt/dnsmadeeasy.ini:/dnsmadeeasy.ini \ -v /etc/letsencrypt:/etc/letsencrypt \ -v /opt/letsencrypt:/script \ certbot/dns-dnsmadeeasy \ certonly \ --dns-dnsmadeeasy \ --dns-dnsmadeeasy-credentials /dnsmadeeasy.ini \ -d zozoandsqueak.ca \ --post-hook '/script/rebuild_certs zozoandsqueak.ca' \ -n
the cron job just runs nightly and dumps its output to a log i can check when it invariably goes wrong
0 0 * * * /usr/local/bin/renew_certs > /var/log/certificate.log 2>&1
i spend half my day writing in org-mode for work, and tried the /ox-gemini/ exporter but it left a bunch of garbage in the output, so i've reverted to just writing straight gemini markup. there's a /gemini-mode/ plugin that provides syntax highlighting and that's made me happy enough. i've just dropped the /gemini-mode.el/ into /~/.doom.d/lisp/ and the following bit of code in my doom [5] config loads it.
(add-to-list 'load-path (expand-file-name "lisp" doom-private-dir)) (require 'gemini-mode)
and this little snippet enables the mode for any file with the /.gmi/ suffix
;; automatically enable gemini-mode for *.gmi files (add-to-list 'auto-mode-alist '("\\.gmi\\'" . gemini-mode))
the content for zozoandsqueak is stored in a private repository on sourcehut [7] and i'm just running a cron job on /misdocker/ to pull the repo into the host directory that's mounted into /content in the gemini container.