Skip to content

0002 — Publish behind Pangolin

Status: Accepted, 2026-10-26 · Decided by: Joakim Persson

Context

The site must be readable by people outside the fleet, at https://pi-atlas.jordbo.se.

Our other public web services already use the same route. A server on the home network runs the Pangolin tunnel client (newt). The client connects out to the Pangolin server, which terminates TLS and forwards requests over the tunnel. The home network needs no open ports.

The Gitea Actions runners that build the site are not on the home network, and nothing has shown that they can reach it. Gitea has a built-in container registry that both the runners and the home server can reach.

Options

  1. CI publishes an image; the server pulls it. CI builds a small nginx image that contains the site and pushes it to the Gitea registry. The server runs that image and pulls new versions.
  2. The server builds the site. The server pulls the repository on a timer, builds the site itself and serves the files.
  3. CI copies the files to the server over SSH. This is how the EGL documentation sites are published.

Decision

Option 1.

  • On every push to main, CI runs the checks first. Only if they pass does it build the image for amd64 and arm64. The image is pushed as :latest and as :sha-<commit>.
  • The image is nginx running as a non-root user. The site files are built inside the image build with the same strict build that CI runs.
  • The server runs :latest from a compose stack in docker-compose-repo. The container joins the network that the tunnel client uses, so Pangolin reaches it by name. No host port is published.

Consequences

  • Only content that passed the checks is ever published, and CI never needs a route into the home network.
  • Rolling back means pinning an older :sha-<commit> tag.
  • CI needs one access token that can write packages, stored as a repository secret.
  • The image is public. Gitea container packages are readable by anyone when their owner account is public, even if the repository is private. Measured on 2026-10-26: an anonymous client pulled the manifest of a package that belongs to a private repository, and the package appeared on the owner's package page for a visitor who was not signed in. Publishing the image therefore publishes the content, whatever access rule Pangolin applies to the website. The writing rules in Contributing already assume a public reader.
  • Pages load the Mermaid renderer from a public CDN, so diagrams need an internet connection in the reader's browser.