Service Update Process
This document outlines the standard operational procedures for updating all containerized and native services hosted on ul. All 30 containerized services (40 containers) run under rootless Podman Quadlets (docker-data, UID 1100); dockerd and containerd are retired. See podman for full architecture and troubleshooting details.
Authentik Update Process
Authentik runs as three rootless Podman Quadlet units (authentik-server.service, authentik-worker.service, and authentik-ldap.service) on authentik_net in /data/docker/authentik/, backed by native loopback PostgreSQL (169.254.1.2:5432) and native ACL-isolated Valkey (169.254.1.2:6379, database 0), with host HAProxy (/etc/haproxy/conf.d/ldap.cfg) forwarding ports 389/636 to :3389/:6636.
1. Determining When an Update is Available
Authentik follows Calendar Versioning (YYYY.M.P, e.g., 2026.8.3).
-
Admin Web UI: Log in to auth.drheck.dev as an administrator and navigate to Admin Interface → System → Overview.
-
GitHub Releases: Monitor the official Authentik Releases page for release tags, changelogs, and release notes.
-
Current Installed Version: Check the running image tags on
ul:# Check configured Quadlet image tags grep '^Image=' /data/docker/authentik/authentik-*.container # Check live running rootless containers (cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman ps --filter name=authentik --format "table {{.Names}}\t{{.Image}}\t{{.Status}}") -
Read the Release Notes for every release between your current version and the target version.
Do not skip minor versions if you are multiple releases behind (e.g., upgrade one minor
YYYY.Mseries at a time and allow database migrations inauthentik-workerandauthentik-serverto finish before proceeding).
2. Update Procedure
Step 1: Perform Pre-Update Backup
Always create an atomic, PAR2-verified snapshot of the PostgreSQL database, configuration files, and .container Quadlet units first:
sudo /home/luke/git/backups/ul/scripts/backup/authentik
Creates /data/backups/services/current/authentik/<YYYY-MM-DD_HHMM.SS>/ containing authentik_db_backup.dump and authentik_files_backup.tar.xz with 10% PAR2 recovery parity.
Step 2: Pull New Container Images
Because all .container units set Pull=never for offline boot resilience, pull the new target images into docker-data's store before editing units:
NEW_VER="2026.8.3"
(cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman pull "ghcr.io/goauthentik/server:${NEW_VER}")
(cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman pull "ghcr.io/goauthentik/ldap:${NEW_VER}")
Step 3: Update Quadlet .container Image Tags
Update Image= in /data/docker/authentik/authentik-{server,worker,ldap}.container:
sudo sed -i "s|^Image=ghcr.io/goauthentik/server:.*|Image=ghcr.io/goauthentik/server:${NEW_VER}|" \
/data/docker/authentik/authentik-server.container \
/data/docker/authentik/authentik-worker.container
sudo sed -i "s|^Image=ghcr.io/goauthentik/ldap:.*|Image=ghcr.io/goauthentik/ldap:${NEW_VER}|" \
/data/docker/authentik/authentik-ldap.container
Step 4: Reload Systemd User Manager & Restart Services
sudo systemctl --user -M docker-data@ daemon-reload
sudo systemctl --user -M docker-data@ restart authentik-worker.service authentik-server.service authentik-ldap.service
Step 5: Monitor Startup & Database Migrations
sudo -u docker-data XDG_RUNTIME_DIR=/run/user/1100 journalctl --user -u authentik-worker.service -u authentik-server.service -f
3. After-Update Verification Checks
- Container & Unit Health:
(cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman ps --filter name=authentik) curl -sk -o /dev/null -w "%{http_code}\n" https://auth.drheck.dev/-/health/live/ - LDAPS Certificate & SSSD Online Check:
(If TLS certificate sync is needed at any time, runopenssl s_client -connect 10.0.0.100:636 -servername auth.drheck.dev </dev/null 2>&1 | grep "Verify return code" sudo sssctl domain-status goauthentik.io --onlinesudo /usr/local/bin/update-authentik-cert.sh.) - SSO Flow Check: Open
https://auth.drheck.dev/and test an OIDC or ForwardAuth app (e.g.,https://scontrol.drheck.dev/orhttps://pw.drheck.dev/).
4. Rollback Procedure (If Upgrade Fails)
# Restore latest backup (or pass an explicit YYYY-MM-DD_HHMM.SS timestamp)
sudo /home/luke/git/backups/ul/scripts/restore/authentik
The restore script verifies PAR2 parity archives, stops authentik-{ldap,server,worker}.service under docker-data, snapshots current files to /data/docker/authentik_rollback_<timestamp>/, restores .env, Quadlets, templates, and PostgreSQL schema/data, and restarts all three units.
Standard Rootless Podman Quadlet Update Workflow
Every containerized service in /data/docker/<service>/ follows a unified backup-first workflow under docker-data:
1. Pre-Update Backup
sudo /home/luke/git/backups/ul/scripts/backup/<service>
2. Updating Registry-Backed Services
- Rolling-Tag Services (
audiomass,bentopdf,bookstack,collabora,degoog,drawpile,excalidraw,funkwhale,navidrome,penpot,romm,step-ca,tldraw,vaultwarden,vikunja,webrcade,wick,yourls):# Pull the new image(s) into docker-data's storage (cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman pull <image_name>) # Restart the Quadlet service unit(s) sudo systemctl --user -M docker-data@ restart <service>.service - Pinned-Tag Services (
anchor,authentik,immich,nextcloud):- Pull the new pinned image tag as
docker-data. - Update
Image=in/data/docker/<service>/<unit>.container(and.envif mirrored there). - Run
sudo systemctl --user -M docker-data@ daemon-reload && sudo systemctl --user -M docker-data@ restart <unit>.service.
- Pull the new pinned image tag as
3. Rebuilding Locally Built Dockerfile Services
Use TMPDIR=/dev/shm so multi-gigabyte builds (demucs and subocr ROCm images) stage layers in RAM:
(cd /data/docker/<service> && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 TMPDIR=/dev/shm podman build -t localhost/<service>:latest /data/docker/<service>)
sudo systemctl --user -M docker-data@ restart <service>.service
Applies to: cam, demucs, grill, scontrol, sopro, subocr, webshell, and wipstudio (localhost/wipstudio:latest).
4. Service-Specific Update Notes
- Degoog (
/data/docker/degoog,search.drheck.dev): Automated source/dependency updates run cleanly inside the container namespace viasudo systemctl start degoog-update.service(/usr/local/bin/degoog-update), preserving subordinate container UID625287ownership. - Immich (
/data/docker/immich,photos.drheck.dev): Pull bothghcr.io/immich-app/immich-server:vX.Y.Zandghcr.io/immich-app/immich-machine-learning:vX.Y.Z-rocm, updateimmich_server.containerandimmich_machine_learning.container, reload, and restart both units. Verify viacurl -sk https://photos.drheck.dev/api/server/ping. - Nextcloud & Collabora (
/data/docker/nextcloud,cloud.drheck.dev,office.drheck.dev): Upgradenextcloud:<version>-apacheone major release at a time, then run post-upgrade index maintenance:(cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman exec -u www-data nextcloud php occ status) (cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman exec -u www-data nextcloud php occ db:add-missing-indices) - RomM (
/data/docker/romm,romm.drheck.dev): Keepfilesystem.structure(default: "roms/{platform}/{game}",firmware: "bios/{platform}") in/data/docker/romm/config/config.ymlfor RomM5.3.0+. - WIPStudio MinIO (
/data/docker/wipstudio,wipstudio.drheck.dev): Upstream removed prebuilt Docker Hub tags; a local xz image archive is preserved at/data/docker/wipstudio/minio_image_backup.tar.xz(podman load -i /data/docker/wipstudio/minio_image_backup.tar.xz), and source updates build via/data/docker/wipstudio/Dockerfile.minio.
Native Systemd Services (postgresql, valkey, nginx, haproxy, forgejo, ollama, podman, openssh)
- Run configuration backups first:
sudo /home/luke/git/backups/ul/scripts/backup/systemd sudo /home/luke/git/backups/ul/scripts/backup/nginx sudo /home/luke/git/backups/ul/scripts/backup/forgejo sudo /home/luke/git/backups/ul/scripts/backup/valkey - Upgrade packages via
pacman:sudo pacman -Sy --noconfirm podman netavark aardvark-dns passt nginx haproxy valkey forgejo ollama ollama-vulkan openssh - Restart updated host services and verify health:
sudo systemctl restart nginx haproxy valkey forgejo ollama sshd systemctl is-active postgresql valkey nginx haproxy forgejo ollama sshd