Skip to content

Development Site

Overview

Field Value
Purpose Serve development/static deployment content
Owner Development team; named owner to be recorded
Criticality Low
Image caddy:2-alpine

Architecture

The restored Forgejo Actions runner publishes build artifacts under the rootless runner data volume on CT 101. A rootless static Caddy container serves the published directory on CT 101, and ingress Caddy on CT 103 should proxy the public/internal hostname to that service.

Installation

Legacy Docker-era deployment paths such as /root/kh3-dev-site are no longer the target design. Use the Forgejo runner data volume, matching the documentation publishing pattern.

Configuration

  • Actions publish path: /opt/podman/volumes/forgejo/runner-data/publish/kh3-dev-site
  • Image cache path: /opt/podman/volumes/forgejo/runner-data/cache/kh3-dev-site-images
  • Static service Quadlet: /home/podsvc/.config/containers/systemd/kh3-dev-site-static.container
  • Static service mount: /opt/podman/volumes/forgejo/runner-data/publish/kh3-dev-site:/srv:ro
  • Static service port: 192.168.2.20:30085
  • Podman network: kh3-backend
  • Ingress route: kh3-dev-site.kh3group.com -> 192.168.2.20:30085
  • Required internal DNS: kh3-dev-site.kh3group.com -> 192.168.2.3

Current Status

Validated on 2026-07-15:

  • Rootless static service kh3-dev-site-static is running on CT 101.
  • Static backend http://127.0.0.1:30085/ returns 200.
  • Ingress Caddy on CT 103 routes kh3-dev-site.kh3group.com to 192.168.2.20:30085.
  • Caddy obtained Let's Encrypt certificates for kh3-dev-site.kh3group.com and proxy.kh3group.com.
  • Internal Caddy test with SNI forced to 192.168.2.3 returned 200.
  • Public https://kh3-dev-site.kh3group.com/ returned 200.
  • Forgejo Actions task 56, triggered by site repo commit 62426aa, refreshed the publish directory. Top-level artifacts under /opt/podman/volumes/forgejo/runner-data/publish/kh3-dev-site now have 2026-07-15 timestamps.

Pending:

  • Add Technitium split-DNS record kh3-dev-site.kh3group.com -> 192.168.2.3. As of the 2026-07-15 validation, Technitium still resolves this name to public Cloudflare addresses 104.21.13.63 and 172.67.198.148. The Technitium API requires an authenticated token; do not edit /etc/dns/zones/*.zone directly because the zone files are Technitium binary format.

On 2026-07-15, validation found the publish directory present but stale, with top-level files last modified on 2026-07-08 before the workflow fix. The live runner config allowed only these bind roots:

/opt/podman/volumes/forgejo/runner-data
/opt/podman/volumes/forgejo/runner-ssh

The site workflow in kh3-dev-site previously referenced /root/kh3-dev-site, which the hardened runner rejects. Commit 2d6c63c in the site repo updated it to mount the runner data volume and publish to /runner-data/publish/kh3-dev-site.

Operational Procedures

ssh pvessh 'pct exec 101 -- runuser -l podsvc -c "XDG_RUNTIME_DIR=/run/user/2000 systemctl --user status kh3-dev-site-static.service --no-pager"'
ssh pvessh 'pct exec 101 -- runuser -l podsvc -c "podman ps --filter name=kh3-dev-site-static"'
ssh pvessh 'curl -I http://192.168.2.20:30085/'

Coordinate changes with Forgejo Actions because the runner writes to the rootless runner artifact directory. The serving container should read the published directory only; it should not own the build or copy step.

Expected workflow volume and deploy target:

container:
  image: node:20-bullseye
  volumes:
    - /opt/podman/volumes/forgejo/runner-data:/runner-data
target=/runner-data/publish/kh3-dev-site
mkdir -p "$target"
rm -rf "$target"/*
cp -a ./dist/. "$target"/
chmod -R 755 "$target"

The deploy step should verify that /runner-data is actually mounted before it copies artifacts. Treat is not a valid volume, will be ignored as a publish failure.

Troubleshooting

Check the most recent Actions deployment, runner volume warnings, file ownership, the static Caddy container logs, ingress Caddy routing, Cloudflare Tunnel origin, and the Technitium local A record.

On 2026-07-15, Cloudflare Tunnel logs showed public requests for kh3-dev-site.kh3group.com reaching the tunnel but being sent to the legacy origin https://proxy.kh3group.com, which failed before routing with tls: internal error. Caddy now has a minimal proxy.kh3group.com compatibility site so the legacy origin can complete TLS. Still prefer correcting the remotely managed Cloudflare Tunnel origin to point directly at the current Caddy ingress path.