Retire Gondulf and move StarPunk to v2.0.0 with Pocket ID login

StarPunk 2.0.0 logs in with Pocket ID and issues its own Micropub tokens
(ADR-064 in the StarPunk repo), so the Gondulf IndieAuth server is no
longer used. Removes its task, templates, Caddy route, subdomain and
service entry, and moves its DNS record to removed_records.

The StarPunk template was still on v1.6.0-rc.2 with Gondulf hairpin
hosts; deploying it would have broken login. It now matches production:
v2.0.0, Pocket ID hairpin, OIDC client from vault_starpunk.pocketid and
the admin sub in starpunk_admin_sub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Phil
2026-10-31 11:52:07 -06:00
co-authored by Claude Opus 5.5
parent a08402f0ac
commit 6dfb58d3f1
13 changed files with 27 additions and 99 deletions
+5 -5
View File
@@ -81,7 +81,7 @@ subdomain.
and the Warhammer RSS feed (09:10).
### Docker role categories (`roles/docker/tasks/<category>/`)
- **infrastructure/**: Caddy, Pocket ID, Gondulf (IndieAuth), Dockge
- **infrastructure/**: Caddy, Pocket ID, Dockge
- **development/**: Gitea (+ act_runner), ByteStash
- **media/**: Audiobookshelf, Kavita, Karakeep (files named `hoarder`), Manyfold
- **productivity/**: Paperless-ngx, Baikal, Syncthing, HeyForm, Dawarich, Obsidian LiveSync, Gokapi
@@ -127,11 +127,11 @@ user (`vault_aws_dns`). It also deletes the records listed under
### SSO (Pocket ID)
Pocket ID (`id.thesatelliteoflove.com`) replaced Authentik on 2026-10-31.
Apps that log in with it: Gitea, ByteStash, Audiobookshelf, Kavita, Karakeep,
Manyfold, Paperless-ngx, Gokapi, GoToSocial. Some read the client from env
Manyfold, Paperless-ngx, Gokapi, GoToSocial, StarPunk. Some read the client from env
vars; Gitea, Audiobookshelf and Kavita store it in their own database (set in
their admin UI). OIDC clients are created in Pocket ID's UI and their ID and
secret go in the vault as `vault_<service>.pocketid`. StarPunk logs in with
IndieAuth through Gondulf instead.
secret go in the vault as `vault_<service>.pocketid`. StarPunk (v2.0.0+) also
runs its own IndieAuth server so Micropub apps can post; Gondulf was retired.
### Shared Docker Network (`lava`)
Created by the docker role as `{{ docker.subnet }}` with `ip_range: {{ docker.ip_range }}`. Docker only hands out dynamic addresses from that range, so `172.20.0.x` is reserved for fixed IPs: Caddy (`docker.hairpin_ip`, .5) and Gitea (`docker.gitea_ip`, .6). Both need fixed IPs because ufw-docker firewall rules point at container IPs. A network without the range (the 2024 original) is migrated once with `migrate-lava-network.yml`.
@@ -146,7 +146,7 @@ extra_hosts:
```
Most often needed for `subdomains.pocketid` (OIDC); also `subdomains.git`
(Gitea itself), `subdomains.gondulf` and `primary_domain` (StarPunk).
(Gitea itself) and `primary_domain` (StarPunk).
### Template pattern
```yaml
+1 -2
View File
@@ -23,7 +23,6 @@ takes ports 80/443 and passes each subdomain to the right container.
|---|---|---|---|
| Infrastructure | Caddy (reverse proxy, static sites) | — | — |
| | Pocket ID (passkey OIDC provider) | id.thesatelliteoflove.com | passkeys |
| | Gondulf (IndieAuth for the main site) | gondulf.thesatelliteoflove.com | email code |
| | Dockge (compose stack manager) | port 5001, no public route | local |
| Development | Gitea + Actions runner | git.thesatelliteoflove.com (SSH on port 222) | Pocket ID |
| | ByteStash (code snippets) | snippets.thesatelliteoflove.com | Pocket ID |
@@ -40,7 +39,7 @@ takes ports 80/443 and passes each subdomain to the right container.
| | Gokapi (file sharing) | gokapi.thesatelliteoflove.com | Pocket ID |
| Communication | GoToSocial (fediverse) | social.thesatelliteoflove.com | Pocket ID |
| | Listmonk (mailing lists) | listmonk.nerder.land | local |
| | StarPunk (Micropub for the main site) | starpunk.thesatelliteoflove.com | IndieAuth |
| | StarPunk (Micropub for the main site) | starpunk.thesatelliteoflove.com | Pocket ID |
| Monitoring | Changedetection | watcher.thesatelliteoflove.com | local |
| | Apprise API (notifications) | Tailscale only, port 8000 | — |
| | Gotify + iGotify assistant | gotify.thesatelliteoflove.com, gotify-assistant.thesatelliteoflove.com | local |
+2 -2
View File
@@ -17,8 +17,6 @@
domains:
- name: thesatelliteoflove.com
dns_records:
- name: "gondulf"
ip: "{{ network.netcup_ip }}"
- name: "starpunk"
ip: "{{ network.netcup_ip }}"
- name: "git"
@@ -88,6 +86,8 @@
ip: "{{ network.netcup_ip }}"
- name: "auth" # Authentik, replaced by Pocket ID
ip: "{{ network.netcup_ip }}"
- name: "gondulf" # IndieAuth, replaced by StarPunk v2 + Pocket ID
ip: "{{ network.netcup_ip }}"
- name: "files"
ip: "{{ network.netcup_ip }}"
- name: "kanboard"
-1
View File
@@ -26,7 +26,6 @@ subdomains:
listmonk: "listmonk.{{ secondary_domain }}" # Listmonk mailing list
gokapi: "gokapi.{{ primary_domain }}" # Gokapi file sharing
pocketid: "id.{{ primary_domain }}" # Pocket ID passkey OIDC
gondulf: "gondulf.{{ primary_domain }}" # IndieAuth for the main site
starpunk: "starpunk.{{ primary_domain }}" # Micropub for the main site
# Email domains for notifications
+4 -1
View File
@@ -2,7 +2,7 @@
# Service categories for organization
service_categories:
infrastructure: ["caddy", "dockge", "gondulf"]
infrastructure: ["caddy", "dockge"]
development: ["gitea", "bytestash"]
media: ["audiobookshelf", "kavita", "hoarder", "manyfold"]
productivity: ["paperlessngx", "baikal", "syncthing", "heyform", "dawarich", "obsidian-livesync", "gokapi"]
@@ -19,5 +19,8 @@ services:
dawarich:
db_name: "dawarich"
db_user: "dawarich"
# StarPunk admin: Pocket ID user ID (sub) of phil
starpunk_admin_sub: "5754855f-0a30-4755-9609-7294209e40f4"
# Gokapi super admin: must match the Pocket ID account email
gokapi_admin_email: "phil@{{ primary_domain }}"
+4 -5
View File
@@ -26,7 +26,6 @@ Tags: each category file has a category tag, each service its own tag.
|---|---|---|
| `caddy` | Caddy | Fixed IP 172.20.0.5. Ports 80/443 (+443/udp). `Caddyfile.j2` changes restart it via a handler; the stack itself is deployed with `recreate: never`. Static sites are served from `/opt/stacks/caddy/site/`. |
| `pocketid` | Pocket ID v2 | Passkey OIDC provider at `id.`. OIDC clients are created in its web UI; their IDs and secrets go in the vault. |
| `gondulf` | Gondulf | IndieAuth server for the main site (own image from Gitea). Sends login codes by email through Resend. |
| `dockge` | Dockge | Compose UI on port 5001, managing `/opt/stacks`. |
### Development (`development`)
@@ -59,7 +58,7 @@ Tags: each category file has a category tag, each service its own tag.
|---|---|---|
| `gotosocial` | GoToSocial | Pocket ID through env vars. Account domain is the apex; Caddy serves WebFinger there. Daily S3 backup of its volume. |
| `listmonk` | Listmonk | Postgres 17. On `listmonk.nerder.land`. |
| `starpunk` | StarPunk | Micropub server for the main site (own image from Gitea). Logs in through Gondulf. |
| `starpunk` | StarPunk | Micropub server for the main site (own image from Gitea). Admin login via Pocket ID; issues its own Micropub tokens. |
### Monitoring (`monitoring`)
| Tag | Service | Notes |
@@ -97,9 +96,9 @@ in from the internet; the Caddy and Gitea task files add those rules.
Containers labelled `mag37.dockcheck.update: true` are updated automatically
each morning by dockcheck (set up in the cron role). Containers without the
label (Gondulf, StarPunk, Listmonk, HeyForm, Dockge and most databases) only
label (StarPunk, Listmonk, HeyForm, Dockge and most databases) only
get a Gotify notice. Dawarich's database and Redis are skipped entirely.
Gondulf and StarPunk use pinned version tags.
StarPunk uses a pinned version tag.
## Adding a service
@@ -121,7 +120,7 @@ roles/docker/
├── tasks/
│ ├── main.yml # System setup, network, category imports
│ ├── shell.yml # zsh, Atuin, bat
│ ├── infrastructure/ # caddy, pocketid, gondulf (+ dockge in main.yml)
│ ├── infrastructure/ # caddy, pocketid (+ dockge in main.yml)
│ ├── development/ # gitea, bytestash
│ ├── media/ # audiobookshelf, kavita, hoarder (Karakeep), manyfold
│ ├── productivity/ # paperlessngx, baikal, syncthing, heyform, dawarich, obsidian-livesync, gokapi
@@ -1,28 +0,0 @@
- name: make gondulf directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
loop:
- /opt/stacks/gondulf
- name: Template out the gondulf compose file
ansible.builtin.template:
src: gondulf-compose.yml.j2
dest: /opt/stacks/gondulf/compose.yml
owner: root
mode: '0644'
- name: Template out the gondulf .env file
ansible.builtin.template:
src: gondulf-env.j2
dest: /opt/stacks/gondulf/.env
owner: root
mode: '0640'
group: docker
diff: false # contains the secret key and SMTP password
- name: deploy gondulf stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/gondulf
files:
- compose.yml
@@ -9,10 +9,6 @@
import_tasks: pocketid.yml
tags: pocketid
- name: Install gondulf
import_tasks: gondulf.yml
tags: gondulf
- name: Template out the dockge compose file
ansible.builtin.template:
src: dockge-compose.yml.j2
-4
View File
@@ -88,10 +88,6 @@ pdg.thesatelliteoflove.com {
}
}
gondulf.thesatelliteoflove.com {
reverse_proxy gondulf:8000
}
starpunk.thesatelliteoflove.com {
reverse_proxy starpunk:8000
}
@@ -1,34 +0,0 @@
services:
gondulf:
image: git.thesatelliteoflove.com/phil/gondulf:1.0.1
container_name: gondulf
restart: unless-stopped
extra_hosts:
- '{{ primary_domain }}:{{ docker.hairpin_ip }}'
volumes:
- gondulf_data:/data
env_file:
- .env
environment:
- GONDULF_HTTPS_REDIRECT=true
- GONDULF_SECURE_COOKIES=true
- GONDULF_TRUST_PROXY=true
- GONDULF_TOKEN_EXPIRY=3600
- GONDULF_CODE_EXPIRY=600
- GONDULF_TOKEN_CLEANUP_ENABLED=false
- GONDULF_TOKEN_CLEANUP_INTERVAL=3600
- GONDULF_LOG_LEVEL=INFO
- GONDULF_DEBUG=false
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
volumes:
# Existing volume (gondulf_gondulf_data) holds the SQLite database
gondulf_data:
networks:
default:
external: true
name: {{ docker.network_name }}
-9
View File
@@ -1,9 +0,0 @@
GONDULF_SECRET_KEY={{ vault_gondulf.secret_key }}
GONDULF_BASE_URL=https://{{ subdomains.gondulf }}
GONDULF_DATABASE_URL=sqlite:////data/gondulf.db
GONDULF_SMTP_HOST={{ smtp.host }}
GONDULF_SMTP_PORT=587
GONDULF_SMTP_USERNAME={{ smtp.username }}
GONDULF_SMTP_PASSWORD={{ vault_smtp.password }}
GONDULF_SMTP_FROM=gondulf@{{ smtp.from_domain }}
GONDULF_SMTP_USE_TLS=true
+10 -3
View File
@@ -1,10 +1,10 @@
services:
starpunk:
image: git.thesatelliteoflove.com/phil/starpunk:v1.6.0-rc.2
image: git.thesatelliteoflove.com/phil/starpunk:v2.0.0
container_name: starpunk
restart: unless-stopped
extra_hosts:
- '{{ subdomains.gondulf }}:{{ docker.hairpin_ip }}'
- '{{ subdomains.pocketid }}:{{ docker.hairpin_ip }}'
- '{{ primary_domain }}:{{ docker.hairpin_ip }}'
volumes:
- starpunk-data:/data
@@ -14,9 +14,16 @@ services:
SITE_NAME: StarPunk
SITE_AUTHOR: Mr Whiskers
SITE_DESCRIPTION: Starpunk instance
# Authentication
# Site owner identity (h-card source, Micropub "me")
ADMIN_ME: https://{{ primary_domain }}
SESSION_SECRET: {{ vault_starpunk.session_secret }}
# Admin login via Pocket ID (client "StarPunk"); only this user may log in.
# StarPunk issues Micropub tokens itself (ADR-064).
OIDC_ISSUER: https://{{ subdomains.pocketid }}
OIDC_CLIENT_ID: {{ vault_starpunk.pocketid.client_id }}
OIDC_CLIENT_SECRET: {{ vault_starpunk.pocketid.client_secret }}
OIDC_ADMIN_SUB: {{ starpunk_admin_sub }}
OIDC_PROVIDER_NAME: Pocket ID
# Production settings
FLASK_ENV: production
FLASK_DEBUG: 0
+1 -1
View File
@@ -21,7 +21,7 @@ Many compose templates repeat the same network, restart and label blocks.
Pull the shared parts into includes or macros.
### Health checks
Only Pocket ID, Gondulf, Dawarich, Listmonk and Syncthing define health checks
Only Pocket ID, Dawarich, Listmonk and Syncthing define health checks
in their templates. Add them to the rest where the image supports it.
### Backups