finish deorbiting gemini capsule

This commit is contained in:
John Bowdre 2024-10-26 16:26:58 -05:00
parent 3af084be32
commit 2739757426
Signed by: john
SSH key fingerprint: SHA256:cZYnOxaLdo+MhBNMX38ihO/p2Kek6fBykSFoJwHBhUo
6 changed files with 13 additions and 104 deletions

View file

@ -7,33 +7,21 @@ DefaultContentLanguage = "en"
enableInlineShortcodes = true enableInlineShortcodes = true
enableRobotsTXT = true enableRobotsTXT = true
# define gemini media type
[mediaTypes]
[mediaTypes.'text/gemini']
suffixes = ["gmi"]
# Automatically add content sections to main menu # Automatically add content sections to main menu
# sectionPagesMenu = "main" # sectionPagesMenu = "main"
[outputs] [outputs]
home = ['html', 'rss', 'gemini'] home = ['html', 'rss']
section = ['html'] section = ['html']
taxonomy = ['html'] taxonomy = ['html']
term = ['html', 'rss', 'gemini'] term = ['html', 'rss']
page = ['html', 'rss', 'gemini'] page = ['html', 'rss']
# rename rss output from index.xml to feed.xml # rename rss output from index.xml to feed.xml
[outputFormats] [outputFormats]
[outputFormats.rss] [outputFormats.rss]
mediatype = "application/rss" mediatype = "application/rss"
baseName = "feed" baseName = "feed"
# gemini output
[outputFormats.gemini]
mediatype = "text/gemini"
isPlainText = true
isHTML = false
protocol = "gemini://"
permalinkable = true
[permalinks] [permalinks]
posts = ":filename" posts = ":filename"

View file

@ -1,7 +1,7 @@
--- ---
title: "Self-Hosted Gemini Capsule with gempost and GitHub Actions" title: "Self-Hosted Gemini Capsule with gempost and GitHub Actions"
date: "2024-03-23T21:33:19Z" date: "2024-03-23T21:33:19Z"
lastmod: "2024-04-05T21:07:38Z" lastmod: "2024-10-26T21:26:17Z"
description: "Deploying a Gemini capsule, powered by Agate, gempost, kineto, Tailscale, and GitHub Actions" description: "Deploying a Gemini capsule, powered by Agate, gempost, kineto, Tailscale, and GitHub Actions"
featured: false featured: false
toc: true toc: true
@ -13,11 +13,17 @@ tags:
- selfhosting - selfhosting
- tailscale - tailscale
--- ---
{{% notice note "Exiting Geminispace..." %}}
After several months of experimentation, I decided to stop exploring Gemini. I still think the concept is really neat but ultimately would rather focus my efforts here in the real world. I'll leave this article in place but my capsule has since been deorbited.
{{% /notice %}}
I've recently been exploring some indieweb/smolweb technologies, and one of the most interesting things I've come across is [Project Gemini](https://geminiprotocol.net/): I've recently been exploring some indieweb/smolweb technologies, and one of the most interesting things I've come across is [Project Gemini](https://geminiprotocol.net/):
> Gemini is a new internet technology supporting an electronic library of interconnected text documents. That's not a new idea, but it's not old fashioned either. It's timeless, and deserves tools which treat it as a first class concept, not a vestigial corner case. Gemini isn't about innovation or disruption, it's about providing some respite for those who feel the internet has been disrupted enough already. We're not out to change the world or destroy other technologies. We are out to build a lightweight online space where documents are just documents, in the interests of every reader's privacy, attention and bandwidth. > Gemini is a new internet technology supporting an electronic library of interconnected text documents. That's not a new idea, but it's not old fashioned either. It's timeless, and deserves tools which treat it as a first class concept, not a vestigial corner case. Gemini isn't about innovation or disruption, it's about providing some respite for those who feel the internet has been disrupted enough already. We're not out to change the world or destroy other technologies. We are out to build a lightweight online space where documents are just documents, in the interests of every reader's privacy, attention and bandwidth.
I thought it was an interesting idea, so after a bit of experimentation with various hosted options I created a self-hosted [Gemini capsule (Gemini for "web site") to host a lightweight text-focused Gemlog ("weblog")](https://capsule.jbowdre.lol/gemlog/2024-03-05-hello-gemini.gmi). After further tinkering, I arranged to serve the capsule both on the Gemini network as well as the traditional HTTP-based web, and I set up a GitHub Actions workflow to handle posting updates. This post will describe how I did that. I thought it was an interesting idea, so after a bit of experimentation with various hosted options I created a self-hosted Gemini capsule (Gemini for "web site") to host a lightweight text-focused Gemlog ("weblog"). After further tinkering, I arranged to serve the capsule both on the Gemini network as well as the traditional HTTP-based web, and I set up a GitHub Actions workflow to handle posting updates. This post will describe how I did that.
### Gemini Server: Agate ### Gemini Server: Agate
There are a number of different [Gemini server applications](https://github.com/kr1sp1n/awesome-gemini?tab=readme-ov-file#servers) to choose from. I decided to use [Agate](https://github.com/mbrubeck/agate), not just because it was at the top of the Awesome Gemini list but also because seems to be widely recommended, regularly updated, and easy to use. Plus it will automatically generates certs for me, which is nice since Gemini *requires* valid certificates for all connections. There are a number of different [Gemini server applications](https://github.com/kr1sp1n/awesome-gemini?tab=readme-ov-file#servers) to choose from. I decided to use [Agate](https://github.com/mbrubeck/agate), not just because it was at the top of the Awesome Gemini list but also because seems to be widely recommended, regularly updated, and easy to use. Plus it will automatically generates certs for me, which is nice since Gemini *requires* valid certificates for all connections.
@ -602,5 +608,5 @@ And the capsule is live at both `https://capsule.jbowdre.lol` and `gemini://caps
![Gemini capsule served over gemini://](gemini-capsule.png) ![Gemini capsule served over gemini://](gemini-capsule.png)
Come check it out! Come check it out!
- [My Capsule on Gemini](gemini://capsule.jbowdre.lol) - My Capsule on Gemini
- [My Capsule on the web](https://capsule.jbowdre.lol) - My Capsule on the web

View file

@ -1,4 +0,0 @@
#!/usr/bin/env bash
# Quick script to serve gemini locally
hugo --environment local -D
agate --content public --hostname localhost

View file

@ -1,12 +0,0 @@
# [runtimeterror $]
=> /about Adventures in self-hosting and other technological frustrations.
{{ $pages := .Pages -}}
{{ $pages = where site.RegularPages "Type" "in" site.Params.mainSections -}}
### Posts
{{ range $pages }}
=> {{ .RelPermalink }} {{ .Date.Format "2006-01-02" }} {{ .Title }}
{{- end }}
---
=> https://runtimeterror.dev This site on the big web

View file

@ -1,10 +0,0 @@
=> / 💻 [runtimeterror $]
# {{ .Title }}
{{- range .Pages }}
=> {{ .RelPermalink }} {{ .Date.Format "2006-01-02" }} {{ .Title }}
{{- end }}
---
=> / Home
=> https://runtimeterror.dev{{ replace (replace .RelPermalink "/gemini" "" 1) "index.gmi" "" }} This page on the big web

View file

@ -1,59 +0,0 @@
{{- $scratch := newScratch -}}{{- $scratch.Set "ref" 1 -}}
=> / 💻 [runtimeterror $]
{{ if .Params.Date }}
{{- $postDate := .Date.Format "2006-01-02" }}
{{- $updateDate := .Lastmod.Format "2006-01-02" }}
{{- $postDate }}{{ if ne $postDate $updateDate }} ~ {{ $updateDate }}{{ end }}
{{- end }}
# {{ .Title }}
{{/* The bulk of this regex magic was inspired by https://brainbaking.com/post/2021/04/using-hugo-to-launch-a-gemini-capsule/ */}}
{{ range $content := split .RawContent "\n\n" }}
{{- $blockRef := $scratch.Get "ref" -}}
{{- $content := $content | replaceRE `#{4,} ` "### " -}}{{/* reduce headings to a max of 3 levels */}}
{{- $content := $content | replaceRE `(?m:^- (.+?)$)` "\n* $1" -}}{{/* convert unordered lists */}}
{{- $content := $content | replaceRE `(?m:^(?:\d+). (.+?)$)` "* $1" -}}{{/* convert ordered lists */}}
{{- $content := $content | replaceRE `\n?\[\^(.+?)\]:\s*.*` "" -}}{{/* remove footnote definitions */}}
{{- $content := $content | replaceRE `\[\^(.+?)\]` "" -}}{{/* remove footnote anchors */}}
{{- $content := $content | replaceRE `((?m:^(?:\|.*\|)+\n?)+)` "```\n$1\n```\n" -}}{{/* render markdown tables as plaintext ascii */}}
{{- $content := $content | replaceRE "(?m:^`([^`]*)`$)" "```\n$1\n```\n" -}}{{/* convert single-line inline code to blocks */}}
{{- $content := $content | replaceRE `\{\{%\snotice.*%\}\}` "<-- note -->" -}}{{/* convert hugo notices */}}
{{- $content := $content | replaceRE `\{\{%\s/notice.*%\}\}` "<-- /note -->" -}}
{{- $content := $content | replaceRE `(?:(?:<!--)|(?:#)|(?:\/\/))\s*torchlight!.*\n` "" -}}{{/* remove torchlight markup */}}
{{- $content := $content | replaceRE `(?:(?:<!--)|(?:#)|(?:\/\/))*\s*\[tl!.*\].*` "" -}}
{{- $content := $content | replaceRE `(?m:^\[!\[(.*)\]\(.*\)\]\((.*)\)$)` "=> $2 $1" -}}{{/* remove images from uptime links */}}
{{- $content := $content | replaceRE `(?m:^\s*(?:(?:\*|\-)\s+)?\[(.*)\]\((.*)\)$)` "=> $2 $1" -}}{{/* convert links already on own line */}}
{{- $content := $content | replaceRE `(?m:^!\[(.*)\]\((.+?)\)$)` "=> $2 Image: $1" -}}{{/* convert embedded images */}}
{{- $links := findRE `\[.+?\]\(.+?\)` $content -}}
{{- $scratch.Set "content" $content -}}
{{- range $links -}}
{{- $ref := $scratch.Get "ref" -}}
{{- $contentInLoop := $scratch.Get "content" -}}
{{- $url := (printf "%s #%d" . $ref) -}}
{{- $contentInLoop := replace $contentInLoop . $url -}}
{{- $scratch.Set "content" $contentInLoop -}}
{{- $scratch.Set "ref" (add $ref 1) -}}
{{- end -}}
{{- $content := $scratch.Get "content" | replaceRE `\[(.+?)\]\((.+?)\) #(\d+)` "$1 [$3]" }}
{{- $content | safeHTML }}
{{- range $links -}}
{{- $ref := $scratch.Get "ref" -}}
{{- $url := (printf "%s #%d" . $blockRef) }}
=> {{ $url | replaceRE `\[(.+?)\]\((.+?)\) #(\d+)` "$2 [$3] $1" }}
{{- $blockRef = add $blockRef 1 -}}
{{ end }}
{{ end }}
---
{{ $subject := printf "Re: %s" .Title -}}
{{ $subject := urlquery $subject | replaceRE `\+` "%20" }}
=> mailto:wheel.east.brief@clkdmail.com?subject={{ $subject }} 📧 Reply by email
{{ $related := first 3 (where (where .Site.RegularPages.ByDate.Reverse ".Params.tags" "intersect" .Params.tags) "Permalink" "!=" .Permalink) }}
{{ if $related }}
## Related articles
{{ range $related }}
=> {{ replace .RelPermalink "/gemini" "" 1}} {{ .Title }}{{ end }}{{ end }}
---
=> / Home
=> https://runtimeterror.dev{{ replace (replace .RelPermalink "/gemini" "" 1) "index.gmi" "" }} This page on the big web