Skip to main content

TISC Editor (Typst)

Online Typst document editor and API, self-hosted for ISC. Migrated onto the rack from the legacy Infomaniak VPS marcellus on 2026-09-18 (external VPS, history).

Guestsrv-tisc-editorLXC 123 on rumba, 192.168.88.36 (static, DHCP-reserved for its MAC on the CCR2004), Debian 13, unprivileged with nesting=1,keyctl=1 (needed for Docker), 1 core / 2 GB / 10 GB
URLhttps://tisc.isc-vs.ch through srv-web01reverse_proxy srv-tisc-editor:8082
SourceISC-HEI/tisc-editor, cloned to /root/tisc-editor on the guest; update with ./publish_new_version.sh (rebuilds the app+docs images, recreates tisc-app-prod/tisc-docs/tisc-nginx; add --db only to (re)initialize Postgres — it drops tisc-db)
AuthThe app is its own Keycloak client (tisc-editor, realm isc) — federates to SWITCH edu-ID directly, no oauth2-proxy gate needed in front of it

Stack

Four containers on one Docker network (tisc-network), started by docker run from publish_new_version.sh (no compose file in production):

ContainerRole
tisc-nginxnginx, the only one bound to the host — 0.0.0.0:8082->80 — fans out / and /api/ws to the app, /docs/ to the docs site
tisc-app-prodNext.js app + Typst compiler, port 3000 (container-internal)
tisc-docsDocusaurus documentation, port 3001 (container-internal)
tisc-dbPostgreSQL 15, port 5432 (container-internal) — the one container publish_new_version.sh leaves alone unless run with --db

Standing rules

danger
AUTH_URL must be the public origin, or logins silently redirect to the LAN

Auth.js (the app's auth library) builds every login redirect from the AUTH_URL env var when it is set, never from the X-Forwarded-* headers a reverse proxy sends. Deployed 2026-09-17 with AUTH_URL=http://192.168.88.36:8082 — reachable from the VPN, a dead end for every other visitor, since the /login redirect pointed at a private IP the Internet cannot route to. Fixed 2026-09-18 to AUTH_URL=https://tisc.isc-vs.ch, with AUTH_TRUST_HOST=true added alongside it (Auth.js's own recommendation behind any reverse proxy). Full account: history. /root/tisc-editor/.env on the guest is the one place to change this; re-run ./publish_new_version.sh (no --db) afterwards to pick it up.

The Caddy vhost targets a hostname, not the guest's IP

Every other backend in provisioning/web/Caddyfile is proxied by raw IP; this one uses the internal DNS name srv-tisc-editor instead, resolved by srv-web01 through its isc3 search domain via the CCR2004's static DNS entry. Convenient — the vhost survives an IP change once the DHCP reservation follows it — but it means a missing or broken internal DNS record for srv-tisc-editor(.isc3) breaks this vhost specifically, with no symptom on any other public site.

Who can reach it

Public, no proxy-level gate — the app's own Keycloak login is the only barrier. 192.168.88.36:8082 is also reachable directly over the LAN/VPN with no authentication in front of it at all (nginx inside the guest does not gate anything); same caution as srv-docker01 — don't rely on the network boundary alone.