mirror of
https://github.com/jbowdre/runtimeterror.git
synced 2024-11-23 07:22:18 +00:00
Merge branch 'main' into drafts
This commit is contained in:
commit
6129e77698
20 changed files with 72 additions and 192 deletions
4
.github/workflows/deploy-prod.yml
vendored
4
.github/workflows/deploy-prod.yml
vendored
|
@ -69,7 +69,3 @@ jobs:
|
||||||
upload: "true"
|
upload: "true"
|
||||||
remove: "true"
|
remove: "true"
|
||||||
purgePullZone: "true"
|
purgePullZone: "true"
|
||||||
- name: Deploy GMI to Agate
|
|
||||||
run: |
|
|
||||||
rsync -avz --delete --exclude='*.html' --exclude='*.css' --exclude='*.js' -e ssh public/ deploy@${{ secrets.GMI_HOST }}:${{ secrets.GMI_CONTENT_PATH }}
|
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -19,7 +19,7 @@ reply = true
|
||||||
name = "John Bowdre"
|
name = "John Bowdre"
|
||||||
email = "jbowdre@omg.lol"
|
email = "jbowdre@omg.lol"
|
||||||
username = "jbowdre"
|
username = "jbowdre"
|
||||||
fedi = "@jbowdre@social.lol"
|
fedi = "@john@srsbsns.lol"
|
||||||
|
|
||||||
[theme]
|
[theme]
|
||||||
palette = "runtimeterror"
|
palette = "runtimeterror"
|
||||||
|
@ -46,6 +46,7 @@ taglines = [
|
||||||
"coding crimes",
|
"coding crimes",
|
||||||
"connection reset by peer",
|
"connection reset by peer",
|
||||||
"converting caffeine into code",
|
"converting caffeine into code",
|
||||||
|
"cowardly refusing to display an empty web page",
|
||||||
"creating new and exciting bugs",
|
"creating new and exciting bugs",
|
||||||
"cyclic dependency detected",
|
"cyclic dependency detected",
|
||||||
"destructor cannot be overloaded",
|
"destructor cannot be overloaded",
|
||||||
|
@ -123,6 +124,7 @@ taglines = [
|
||||||
"write error: no space left on device",
|
"write error: no space left on device",
|
||||||
"you can't handle the exception",
|
"you can't handle the exception",
|
||||||
"you gotta stop letting your mama test you, man",
|
"you gotta stop letting your mama test you, man",
|
||||||
|
"your browser is deprecated. please upgrade.",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Sidebar: social links
|
# Sidebar: social links
|
||||||
|
@ -145,11 +147,6 @@ icon = "fa-solid fa-pen-to-square"
|
||||||
title = "Weblog"
|
title = "Weblog"
|
||||||
url = "https://srsbsns.lol"
|
url = "https://srsbsns.lol"
|
||||||
|
|
||||||
[[socialLinks]]
|
|
||||||
icon = "fa-solid fa-satellite"
|
|
||||||
title = "Gemini Capsule"
|
|
||||||
url = "gemini://capsule.jbowdre.lol"
|
|
||||||
|
|
||||||
[[socialLinks]]
|
[[socialLinks]]
|
||||||
icon = "fa-solid fa-circle-user"
|
icon = "fa-solid fa-circle-user"
|
||||||
title = "CounterSocial"
|
title = "CounterSocial"
|
||||||
|
@ -158,7 +155,7 @@ url = "https://counter.social/@john_b"
|
||||||
[[socialLinks]]
|
[[socialLinks]]
|
||||||
icon = "fa fa-mastodon"
|
icon = "fa fa-mastodon"
|
||||||
title = "Mastodon"
|
title = "Mastodon"
|
||||||
url = "https://social.lol/@jbowdre"
|
url = "https://goto.srsbsns.lol/@john"
|
||||||
|
|
||||||
[[socialLinks]]
|
[[socialLinks]]
|
||||||
icon = "fa-solid fa-envelope"
|
icon = "fa-solid fa-envelope"
|
||||||
|
@ -203,10 +200,6 @@ url = "https://proven.lol/cd10d3"
|
||||||
title = "CounterSocial"
|
title = "CounterSocial"
|
||||||
url = "https://counter.social/@john_b"
|
url = "https://counter.social/@john_b"
|
||||||
|
|
||||||
[[verifyLinks]]
|
|
||||||
title = "Mastodon"
|
|
||||||
url = "https://social.lol/@jbowdre"
|
|
||||||
|
|
||||||
[[verifyLinks]]
|
[[verifyLinks]]
|
||||||
title = "GitHub"
|
title = "GitHub"
|
||||||
url = "https://github.com/jbowdre"
|
url = "https://github.com/jbowdre"
|
||||||
|
|
|
@ -28,14 +28,13 @@ And in the free time I have left, I game on my Steam Deck.
|
||||||
### See what I've been up to on:
|
### See what I've been up to on:
|
||||||
- [GitHub](https://github.com/jbowdre)
|
- [GitHub](https://github.com/jbowdre)
|
||||||
- [Weblog](https://srsbsns.lol)
|
- [Weblog](https://srsbsns.lol)
|
||||||
- [Gemlog](https://capsule.jbowdre.lol/gemlog/)
|
|
||||||
- [status.lol](https://status.jbowdre.lol)
|
- [status.lol](https://status.jbowdre.lol)
|
||||||
- [social.lol](https://social.lol/@jbowdre)
|
- [Fediverse](https://goto.srsbsns.lol/@john)
|
||||||
- [CounterSocial](https://counter.social/@john_b)
|
- [CounterSocial](https://counter.social/@john_b)
|
||||||
- [/now](https://now.jbowdre.lol)
|
- [/now](https://now.jbowdre.lol)
|
||||||
|
|
||||||
### Connect with me via:
|
### Connect with me via:
|
||||||
- [SimpleX Chat](/simplex/)
|
- [SimpleX Chat](https://l.runtimeterror.dev/simplex-chat-invite)
|
||||||
- [Signal](https://signal.me/#eu/lyHZbMnlM16O0w48j3rshYBofO0K-iXOt9LGwln7TS-fNKEHCrxH3La325q8IjRU)
|
- [Signal](https://signal.me/#eu/lyHZbMnlM16O0w48j3rshYBofO0K-iXOt9LGwln7TS-fNKEHCrxH3La325q8IjRU)
|
||||||
- [Matrix](https://matrix.to/#/@jbowdre:omg.lol)
|
- [Matrix](https://matrix.to/#/@jbowdre:omg.lol)
|
||||||
- [XMPP](https://conversations.im/i/jbowdre@omg.lol?omemo-sid-1374125881=a620f3c57733601a6646f6f13a71c86fc9be8dd4126fd158ef3e0a26beb0b434)
|
- [XMPP](https://conversations.im/i/jbowdre@omg.lol?omemo-sid-1374125881=a620f3c57733601a6646f6f13a71c86fc9be8dd4126fd158ef3e0a26beb0b434)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: "/changelog"
|
title: "/changelog"
|
||||||
date: "2024-05-26T21:19:08Z"
|
date: "2024-05-26T21:19:08Z"
|
||||||
lastmod: "2024-08-21T03:11:27Z"
|
lastmod: "2024-10-20T03:51:49Z"
|
||||||
description: "Maybe I should keep a log of all my site-related tinkering?"
|
description: "Maybe I should keep a log of all my site-related tinkering?"
|
||||||
featured: false
|
featured: false
|
||||||
toc: false
|
toc: false
|
||||||
|
@ -10,6 +10,9 @@ categories: slashes
|
||||||
---
|
---
|
||||||
*Running list of config/layout changes to the site. The full changelog is of course [on GitHub](https://github.com/jbowdre/runtimeterror/commits/main/).*
|
*Running list of config/layout changes to the site. The full changelog is of course [on GitHub](https://github.com/jbowdre/runtimeterror/commits/main/).*
|
||||||
|
|
||||||
|
**2024-10-19:**
|
||||||
|
- Shut down Gemini mirror, removed links pointing to it
|
||||||
|
|
||||||
**2024-08-20:**
|
**2024-08-20:**
|
||||||
- Added anchor links on section headings
|
- Added anchor links on section headings
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: "/colophon"
|
title: "/colophon"
|
||||||
date: "2024-05-26T22:30:58Z"
|
date: "2024-05-26T22:30:58Z"
|
||||||
lastmod: "2024-08-02T21:16:41Z"
|
lastmod: "2024-10-20T03:51:35Z"
|
||||||
description: "There's a lot that goes into this site. Let me tell you how it works."
|
description: "There's a lot that goes into this site. Let me tell you how it works."
|
||||||
featured: false
|
featured: false
|
||||||
toc: true
|
toc: true
|
||||||
|
@ -21,7 +21,6 @@ categories: slashes
|
||||||
- displays my latest status from [omg.lol](https://home.omg.lol/referred-by/jbowdre).
|
- displays my latest status from [omg.lol](https://home.omg.lol/referred-by/jbowdre).
|
||||||
- resolves via [Bunny DNS](https://bunny.net/dns/).
|
- resolves via [Bunny DNS](https://bunny.net/dns/).
|
||||||
- is published to / hosted on [Bunny Storage](https://bunny.net/storage/) and [Bunny CDN](https://bunny.net/cdn/) with a [GitHub Actions workflow](//further-down-the-bunny-hole/).
|
- is published to / hosted on [Bunny Storage](https://bunny.net/storage/) and [Bunny CDN](https://bunny.net/cdn/) with a [GitHub Actions workflow](//further-down-the-bunny-hole/).
|
||||||
- has a [Gemini](https://geminiprotocol.net) mirror at `gemini://gmi.runtimeterror.dev`. This is generated from a [Hugo gemtext post layout](https://github.com/jbowdre/runtimeterror/blob/main/layouts/_default/single.gmi), deployed to a [Vultr](https://www.vultr.com/) VPS through that same GitHub Actions workflow, and served with [Agate](https://github.com/mbrubeck/agate).
|
|
||||||
|
|
||||||
The post content is licensed under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/); the site code is under the [MIT License](https://github.com/jbowdre/runtimeterror/blob/main/LICENSE).
|
The post content is licensed under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/); the site code is under the [MIT License](https://github.com/jbowdre/runtimeterror/blob/main/LICENSE).
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: "/homelab"
|
title: "/homelab"
|
||||||
date: "2024-05-26T21:30:51Z"
|
date: "2024-05-26T21:30:51Z"
|
||||||
lastmod: "2024-09-22T19:16:04Z"
|
lastmod: "2024-10-23T02:10:13Z"
|
||||||
aliases:
|
aliases:
|
||||||
- playground
|
- playground
|
||||||
description: "The systems I use for fun and enrichment."
|
description: "The systems I use for fun and enrichment."
|
||||||
|
@ -14,7 +14,7 @@ categories: slashes
|
||||||
|
|
||||||
Everything is connected to my [Tailscale](https://tailscale.com) tailnet, with a GitOps-managed ACL to allow access as needed. This lets me access and manage systems without really caring if they're local or remote. [Tailscale is magic](/secure-networking-made-simple-with-tailscale/).
|
Everything is connected to my [Tailscale](https://tailscale.com) tailnet, with a GitOps-managed ACL to allow access as needed. This lets me access and manage systems without really caring if they're local or remote. [Tailscale is magic](/secure-networking-made-simple-with-tailscale/).
|
||||||
|
|
||||||
The Docker containers are (generally) managed with [Portainer](https://www.portainer.io/).
|
The Docker containers are (generally) managed with [Portainer](https://www.portainer.io/) using configs [on GitHub](https://github.com/jbowdre/compositions).
|
||||||
|
|
||||||
### On Premise
|
### On Premise
|
||||||
|
|
||||||
|
@ -35,9 +35,13 @@ The Proxmox cluster hosts a number of VMs and LXC containers:
|
||||||
- `doc`: Ubuntu 22.04 Docker host for various on-prem container workloads, served via [Tailscale Serve](/tailscale-ssh-serve-funnel/#tailscale-serve) / [Caddy + Tailscale](/caddy-tailscale-alternative-cloudflare-tunnel/):
|
- `doc`: Ubuntu 22.04 Docker host for various on-prem container workloads, served via [Tailscale Serve](/tailscale-ssh-serve-funnel/#tailscale-serve) / [Caddy + Tailscale](/caddy-tailscale-alternative-cloudflare-tunnel/):
|
||||||
- [Calibre Web](https://github.com/janeczku/calibre-web) for managing my ebooks
|
- [Calibre Web](https://github.com/janeczku/calibre-web) for managing my ebooks
|
||||||
- [Cyberchef](https://github.com/gchq/CyberChef), the Cyber Swiss Army Knife
|
- [Cyberchef](https://github.com/gchq/CyberChef), the Cyber Swiss Army Knife
|
||||||
|
- [Golink](https://github.com/tailscale/golink), a private shortlink service for tailnets
|
||||||
- [Hashicorp Vault](https://www.vaultproject.io/) for secrets management
|
- [Hashicorp Vault](https://www.vaultproject.io/) for secrets management
|
||||||
|
- [Heimdall](https://github.com/linuxserver/Heimdall), an application dashboard and launcher
|
||||||
|
- [IT-Tools](https://github.com/CorentinTh/it-tools) for handy online development-related tools
|
||||||
|
- [Linkding](https://github.com/sissbruecker/linkding) bookmark manager serving [links.bowdre.net](https://links.bowdre.net/bookmarks/shared)
|
||||||
- [RIPE Atlas Probe](https://www.ripe.net/analyse/internet-measurements/ripe-atlas/) for measuring internet connectivity
|
- [RIPE Atlas Probe](https://www.ripe.net/analyse/internet-measurements/ripe-atlas/) for measuring internet connectivity
|
||||||
- [SilverBullet](https://silverbullet.md), a web-based personal knowledge management system ([post](https://srsbsns.lol/is-silverbullet-the-note-keeping-silver-bullet/))
|
- [SilverBullet](https://silverbullet.md), a web-based personal knowledge management system ([post](/publish-silverbullet-notes-quartz/))
|
||||||
- [Tailscale Golink](https://github.com/tailscale/golink), a private shortlink service ([post](/tailscale-golink-private-shortlinks-tailnet/))
|
- [Tailscale Golink](https://github.com/tailscale/golink), a private shortlink service ([post](/tailscale-golink-private-shortlinks-tailnet/))
|
||||||
- `files`: Ubuntu 20.04 file server. Serves (selected) files semi-publicly through [Tailscale Funnel](/tailscale-ssh-serve-funnel/#tailscale-funnel)
|
- `files`: Ubuntu 20.04 file server. Serves (selected) files semi-publicly through [Tailscale Funnel](/tailscale-ssh-serve-funnel/#tailscale-funnel)
|
||||||
- `hassos`: [Home Assistant OS](https://www.home-assistant.io/installation/), manages all my "smart home" stuff ([post](/automating-camera-notifications-home-assistant-ntfy/))
|
- `hassos`: [Home Assistant OS](https://www.home-assistant.io/installation/), manages all my "smart home" stuff ([post](/automating-camera-notifications-home-assistant-ntfy/))
|
||||||
|
@ -63,11 +67,13 @@ This triad of cute little single-board computers will *eventually* be a combinat
|
||||||
|
|
||||||
I like to know what's flying overhead, and I'm also feeding flight data to [flightaware.com](https://flightaware.com) and [adsb.fi](https://adsb.fi).
|
I like to know what's flying overhead, and I'm also feeding flight data to [flightaware.com](https://flightaware.com) and [adsb.fi](https://adsb.fi).
|
||||||
|
|
||||||
### Cloud
|
**Federated Raspberry Pi**
|
||||||
|
- Raspberry Pi 4 Model B
|
||||||
|
- 64GB Sandisk USB Drive
|
||||||
|
|
||||||
**[Oracle Cloud Infrastructure](https://www.oracle.com/cloud/free/)**
|
Runs [GoToSocial](https://gotosocial.org/) in Docker to host my personal Mastodon-compatible ActivityPub server, [goto.srsbsns.lol](https://goto.srsbsns.lol) ([post](https://srsbsns.lol/going-to-gotosocial/)).
|
||||||
- `git`: Ubuntu 22.04 [Forgejo](https://forgejo.org/) server for [git.bowdre.net](https://git.bowdre.net/explore/repos)
|
|
||||||
- `smp2`: Ubuntu 22.04 [SimpleX](/simplex/) server
|
### Cloud
|
||||||
|
|
||||||
**[Google Cloud Platform](https://cloud.google.com/free/docs/free-cloud-features)**
|
**[Google Cloud Platform](https://cloud.google.com/free/docs/free-cloud-features)**
|
||||||
- `smp`: Ubuntu 22.04 [SimpleX](/simplex/) server
|
- `smp`: Ubuntu 22.04 [SimpleX](/simplex/) server
|
||||||
|
@ -75,10 +81,8 @@ I like to know what's flying overhead, and I'm also feeding flight data to [flig
|
||||||
|
|
||||||
**[Vultr](https://www.vultr.com)**
|
**[Vultr](https://www.vultr.com)**
|
||||||
- `volly`: Ubuntu 22.04 Docker host for various workloads, served either through [Caddy](https://caddyserver.com/) or [Caddy + Tailscale](/caddy-tailscale-alternative-cloudflare-tunnel/):
|
- `volly`: Ubuntu 22.04 Docker host for various workloads, served either through [Caddy](https://caddyserver.com/) or [Caddy + Tailscale](/caddy-tailscale-alternative-cloudflare-tunnel/):
|
||||||
- [Agate](https://github.com/mbrubeck/agate) Gemini server ([post](/gemini-capsule-gempost-github-actions/))
|
- [Forgejo](https://forgejo.org/) server for [git.bowdre.net](https://git.bowdre.net/explore/repos) ([post](/gitea-self-hosted-git-server/))
|
||||||
- [Kineto](https://github.com/beelux/kineto) Gemini-to-HTTP proxy ([post](/gemini-capsule-gempost-github-actions/))
|
|
||||||
- [Linkding](https://github.com/sissbruecker/linkding) bookmark manager serving [links.bowdre.net](https://links.bowdre.net/bookmarks/shared)
|
|
||||||
- [ntfy](https://ntfy.sh/) notification service ([post](/easy-push-notifications-with-ntfy/))
|
- [ntfy](https://ntfy.sh/) notification service ([post](/easy-push-notifications-with-ntfy/))
|
||||||
- [SearXNG](https://docs.searxng.org/) self-hosted metasearch engine serving [grep.vpota.to](https://grep.vpota.to) ([post](https://srsbsns.lol/post/self-hosting-a-search-engine-iyjdlk6y))
|
- [SimpleX](/simplex/) server (`smp2`)
|
||||||
- [Uptime Kuma](https://github.com/louislam/uptime-kuma) for monitoring internal services (via Tailscale)
|
- [Uptime Kuma](https://github.com/louislam/uptime-kuma) for monitoring internal services (via Tailscale)
|
||||||
- [vault-unseal](https://github.com/lrstanley/vault-unseal) to auto-unseal my on-prem Vault instance
|
- [vault-unseal](https://github.com/lrstanley/vault-unseal) to auto-unseal my on-prem Vault instance
|
||||||
|
|
|
@ -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
|
|
@ -160,7 +160,8 @@ No users have added their keys to Gitea just yet so if you look at `/home/git/.s
|
||||||
|
|
||||||
So I'll go ahead and create that extra command:
|
So I'll go ahead and create that extra command:
|
||||||
```shell
|
```shell
|
||||||
cat <<"EOF" | sudo tee /usr/local/bin/gitea # [tl! .cmd]
|
# [tl! .cmd:1,1]
|
||||||
|
cat <<EOF | sudo tee /usr/local/bin/gitea
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
|
ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: "Publishing SilverBullet Notes with Quartz and GitHub Actions"
|
title: "Publishing (Selected) SilverBullet Notes with Quartz and GitHub Actions"
|
||||||
date: "2024-09-29T20:27:03Z"
|
date: "2024-09-29T20:27:03Z"
|
||||||
# lastmod: 2024-09-28
|
# lastmod: 2024-09-28
|
||||||
description: "A long note about how I publish short notes from SilverBullet using Quartz, Tailscale, Caddy, and GitHub Actions."
|
description: "A long note about how I publish short notes from SilverBullet using Quartz, Tailscale, Caddy, and GitHub Actions."
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: "Tailscale Serve in a Docker Compose Sidecar"
|
title: "Tailscale Serve in a Docker Compose Sidecar"
|
||||||
date: 2023-12-30
|
date: 2023-12-30
|
||||||
lastmod: 2024-02-07
|
lastmod: "2024-10-21T01:37:12Z"
|
||||||
description: "Using Docker Compose to deploy containerized applications and make them available via Tailscale Serve and Tailscale Funnel"
|
description: "Using Docker Compose to deploy containerized applications and make them available via Tailscale Serve and Tailscale Funnel"
|
||||||
featured: false
|
featured: false
|
||||||
toc: true
|
toc: true
|
||||||
|
@ -86,6 +86,31 @@ Tailscale [just published a blog post](https://tailscale.com/blog/docker-tailsca
|
||||||
|
|
||||||
Replace the ports and protocols and hostnames and such, and you'll be good to go.
|
Replace the ports and protocols and hostnames and such, and you'll be good to go.
|
||||||
|
|
||||||
|
**Update 2024-10-20**: I recently learned that you can use the `${TS_CERT_DOMAIN}` placeholder to avoid having to hardcode a hostname into the `serve-config.json`. That makes the config even easier to reuse:
|
||||||
|
|
||||||
|
```json
|
||||||
|
// torchlight! {"lineNumbers": true}
|
||||||
|
{ // [tl! collapse:start]
|
||||||
|
"TCP": {
|
||||||
|
"443": {
|
||||||
|
"HTTPS": true
|
||||||
|
}
|
||||||
|
},// [tl! collapse:end]
|
||||||
|
"Web": {
|
||||||
|
"${TS_CERT_DOMAIN}:443": { // [tl! collapse:start]
|
||||||
|
"Handlers": {
|
||||||
|
"/": {
|
||||||
|
"Proxy": "http://127.0.0.1:8000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//, uncomment to enable funnel [tl! collapse:end]
|
||||||
|
// "AllowFunnel": {
|
||||||
|
// "${TS_CERT_DOMAIN}:443": true
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
A compose config using this setup might look something like this:
|
A compose config using this setup might look something like this:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|
|
@ -1,53 +1,4 @@
|
||||||
+++
|
|
||||||
reply = false
|
|
||||||
toc = false
|
|
||||||
usePageBundles = false
|
|
||||||
showDate = false
|
|
||||||
showShare = false
|
|
||||||
showReadTime = false
|
|
||||||
timeless = true
|
|
||||||
title = "SimpleX Chat"
|
|
||||||
+++
|
|
||||||
> You can [contact me on SimpleX Chat](https://l.runtimeterror.dev/simplex-chat-invite) by clicking that link or scanning the QR code below.
|
|
||||||
|
|
||||||
![QR code](/images/simplex-invite.png)
|
|
||||||
|
|
||||||
[SimpleX Chat](https://simplex.chat/) is a secure messaging solution with a strong emphasis on user privacy. It's (naturally) end-to-end encrypted, doesn't require (or collect) *any* information about you in order to sign up, doesn't use any persistent user identifiers (not even a randomly-generated one), is fully decentralized, and is *not* affiliated with any cryptocurrency project/scam.
|
|
||||||
|
|
||||||
Incoming messages are routed through a pool of servers so that your conversations don't all follow the same path - and no server knows anything about conversations that aren't routed through it. Servers only hold your messages long enough to ensure they get to you, and those messages exist only in the encrypted database on your device once they've been delivered. (Fortunately, SimpleX makes it easy to back up that database and restore it on a new device so you don't lose any messages or contacts.)
|
|
||||||
|
|
||||||
The app is also packed with other features like disappearing messages, encrypted file transfers, encrypted voice messages, encrypted audio and video calls, decentralized private groups, and a cool incognito mode which connects new conversations to a randomly-generated profile instead of your primary one. There's even a [CLI client](https://github.com/simplex-chat/simplex-chat/blob/stable/docs/CLI.md)!
|
|
||||||
|
|
||||||
## Servers
|
|
||||||
You can easily host your own [simplexmq server](https://github.com/simplex-chat/simplexmq) for handling your inbound message queue, and I've done just that; in fact, I've deployed three! And, as one of my closest internet friends, *you're welcome to use them as well.*
|
|
||||||
|
|
||||||
Just add these in the SimpleX app at **Settings > Network & servers > SMP servers > + Add server...**. Enable the option to use them for new connections, and they'll be added to the pool used for incoming messages in new conversations. If you want to use them immediately for existing conversations, go into each conversation's options menu and use the **Switch receiving address** option. You can also *disable* the option to use the default servers for new conversations if you only want messages to be routed through specific servers, but that does increase the likelikhood of concurrent conversations being routed the same way. More servers, more path options, less metadata in any one place.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
![QR code](/images/smp-vpota-to.png)
|
type: redirect
|
||||||
|
target: https://l.runtimeterror.dev/simplex-chat-invite
|
||||||
`smp://kYx5LmVD9FMM8hJN4BQqL4WmeUNZn8ipXsX2UkBoiHE=@smp.vpota.to`
|
|
||||||
|
|
||||||
[![Uptime](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjbowdre%2Fupptime%2Fmaster%2Fapi%2Fsmp-vpota-to-5223%2Fuptime.json)](https://status.runtimeterror.dev/history/smp-vpota-to-5223)
|
|
||||||
|
|
||||||
[netdata](https://l.runtimeterror.dev/smp_status)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
![QR code](/images/smp1-vpota-to.png)
|
|
||||||
|
|
||||||
`smp://TbUrGydawdVKID0Lvix14UkaN-WarFgqXx4kaEG8Trw=@smp1.vpota.to`
|
|
||||||
|
|
||||||
[![Uptime](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjbowdre%2Fupptime%2Fmaster%2Fapi%2Fsmp1-vpota-to-5223%2Fuptime.json)](https://status.runtimeterror.dev/history/smp1-vpota-to-5223)
|
|
||||||
|
|
||||||
[netdata](https://l.runtimeterror.dev/smp1_status)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
![QR code](/images/smp2-vpota-to.png)
|
|
||||||
|
|
||||||
`smp://tNfQisxTQ9MhKpFDTbx9RnjgWigtxF1a26jroy5-rR4=@smp2.vpota.to`
|
|
||||||
|
|
||||||
[![Uptime](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjbowdre%2Fupptime%2Fmaster%2Fapi%2Fsmp2-vpota-to-5223%2Fuptime.json)](https://status.runtimeterror.dev/history/smp2-vpota-to-5223)
|
|
||||||
|
|
||||||
[netdata](https://l.runtimeterror.dev/smp2_status)
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Quick script to serve gemini locally
|
|
||||||
hugo --environment local -D
|
|
||||||
agate --content public --hostname localhost
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
Binary file not shown.
Before Width: | Height: | Size: 54 KiB |
Binary file not shown.
Before Width: | Height: | Size: 41 KiB |
Binary file not shown.
Before Width: | Height: | Size: 42 KiB |
Binary file not shown.
Before Width: | Height: | Size: 42 KiB |
Loading…
Reference in a new issue