RedlineKnowledge base

Fridai Redline setup

Fridai Redline has two independently deployed parts:

  1. @fridai/fio-redline, the Astro adapter and UI package used by a knowledge site (published under Fridai CalVer versioning).
  2. fio-redline, the containerized API hosted beside the Fridai GitLab instance and published at https://yqa.fio.sh through Cloudflare Tunnel and Cloudflare Access.

Deployment architecture

Browser -> Cloudflare Access -> yqa.fio.sh -> Cloudflare Tunnel
        -> cloudflared -> review service -> glab.fio.sh-bridge -> GitLab

Browser on Tailscale -> glab.fio.sh -> host nginx -> GitLab

cloudflared and the review service run as containers. The review service joins the existing external Docker network glab.fio.sh-bridge and calls GitLab at http://glab.fio.sh-server. Browser redirects and links continue to use https://glab.fio.sh. The glab.fio.sh Tailscale A record and host nginx configuration are not changed.

Workers VPC is not part of this deployment. It would only be needed if the API application continued to execute in a Cloudflare Worker.

Start here

Security model

Cloudflare Access authenticates the person entering yqa.fio.sh. GitLab OAuth then delegates that person’s GitLab permissions to the service. Read-only history uses a project token; comments, edits, approvals, and merges use only the connected user’s OAuth token. GitLab therefore remains the authoritative record of the actor.

The initial deployment starts with WRITE_ENABLED=false. After read-only and OAuth smoke tests pass, writes can be enabled while the per-site merging feature remains false. Approval requests include the expected merge-request HEAD SHA so an approval cannot silently apply to a revision that changed after the user reviewed it.

Experiment deployment (Tailscale-only)

Step-by-step instructions: Redline experiment: operator setup. To run QA on any tailnet computer instead of the GitLab host, use Redline local QA.

The redline experiment runs the same service without Cloudflare Access or Tunnel: the network is the perimeter and GitLab OAuth is the identity. The topology, cookie and CORS constraints, and the three failure states are in the experiment network design.

  • Start the stack without the tunnel profile (docker compose up -d); the cloudflared sidecar runs only with --profile tunnel. Host nginx is the ingress for yqa.fio.sh.
  • Set IDENTITY_MODE=gitlab-oauth, REQUIRE_ACCESS=false, ALLOW_ANONYMOUS_READ=true, WRITE_ENABLED=true and, for the site, features.editing=false (see ops/service.env.example). The ACCESS_* values and the tunnel token are not needed.
  • Each environment serves Redline’s dashboard and its API on one origin and registers the fio-redline site with that origin. Production at https://yqa.fio.sh tracks the released channel; persistent QA at https://qa-yqa.fio.sh tracks verified and starts with docker compose --profile qa up -d (ops/.env.example, ops/service-qa.env.example, and its own ops/secrets/session-secret-qa).
  • One GitLab OAuth application serves both environments: list both redirect URIs, one per line, https://yqa.fio.sh/v1/auth/gitlab/callback and https://qa-yqa.fio.sh/v1/auth/gitlab/callback.

Operator inputs:

ItemValue or owner
DNSyqa.fio.sh and qa-yqa.fio.sh A records → GitLab host Tailscale IP, same zone as glab.fio.sh
TLShost nginx vhosts yqa.fio.sh and qa-yqa.fio.sh, certificates by the same method as glab.fio.sh
nginx upstreamfio-redline:8787 (production) and fio-redline-qa:8787 (QA) on the Docker network, or published loopback ports
GitLab OAuth appconfidential, scope api, redirect URIs for both hosts (/v1/auth/gitlab/callback), one per line
GitLab read tokenproject or group token, read_api only
Site registrationSITES_JSON for yyz as in ops/service.env.example, with features.editing=false
Secretsops/secrets/* files as the compose file lists, except the tunnel token

Container registry

GitLab CI publishes the service image to:

glab.fio.sh:5050/fridai/fio-dep/fio-redline/fio-redline

Every pushed commit receives an immutable sha-<short-sha> tag and a mutable branch tag. main, exact release tags, next, and latest are added only in their corresponding release contexts. Production should pin an immutable SHA or exact release tag. The publish job verifies the immutable manifest through the same canonical :5050 endpoint used by deployment hosts and prints the complete deployable reference as DEPLOY_IMAGE.

CI uploads through the runner-reachable registry origin on :10505 and then verifies and reports the canonical :5050 reference. Only the canonical reference is valid in deployment configuration.

Git history

Loading the page's history…