Files
flamenet-relay/docker-compose.yml
Paul HittandClaude Opus 5.5 93d0986a2b
ci / checks (pull_request) Successful in 16s
ci / image (pull_request) Failing after 2m2s
ci / deploy (pull_request) Skipped
ci / swift (pull_request) Successful in 10m44s
CI: move to Gitea Actions; build and gate off the box, deploy over SSH
.gitlab-ci.yml becomes .gitea/workflows/ci.yml on mac1/mac2 (amd64), with
the same checks: secret sweep, swift build and test on swift:6.1-noble,
section 8 conformance at the pinned e2e commit, doc-page hashes, the
configuration doc and package completeness (HEAD variants advisory).

The image is built with --build-arg FN_RELEASE=<sha> and the staging gate
(Scripts/ci-staging-gate.sh, same checks as staging-gate.sh) runs against
that image before it is pushed. On main, deploy/gitea-deploy.sh pulls the
gated image on the box, dumps the database, tags it flamenet-relay:prod,
checks the edge and key_log row count, rolls back to :previous on failure,
and recreates the test fleet. The self-host compose pulls from
git.extant2000.com.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:05:48 -04:00

102 lines
4.7 KiB
YAML

# Flamenet relay + Postgres.
#
# 1. cp .env.example .env and fill in the two secrets it asks for
# 2. docker compose up -d
# 3. open http://localhost:8080
#
# The relay serves its own landing page, so a working install explains itself
# rather than answering with a 404.
services:
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: flamenet
POSTGRES_USER: flamenet
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}"
volumes:
- db-data:/var/lib/postgresql/data
# Not published on the host: the relay reaches it over the compose network,
# and an exposed database is the kind of default that ends up on Shodan.
expose:
- "5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U flamenet -d flamenet"]
interval: 5s
timeout: 5s
retries: 10
relay:
# The published image, so getting a relay running does not require a
# Swift toolchain and several minutes of compiling on what is often a small
# VPS. Built and pushed by this project's own CI from `main`.
#
# amd64 only. CI builds for its runner's architecture. On a
# Raspberry Pi or an ARM VPS, build from source instead:
#
# docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
#
# Pin this to a commit sha (`:abc1234`) rather than `:latest` if you
# want to choose when you move. `latest` is what a person wants the first
# time and rarely what they want on the tenth.
image: git.extant2000.com/extant2000/flamenet-relay:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
FN_HOST: "0.0.0.0"
# Errors and criticals only. `debug` logs request URLs and SQL, and a
# §8 URL contains a device id.
FN_LOG_LEVEL: "${FN_LOG_LEVEL:-error}"
FN_POSTGRES_URL: "postgres://flamenet:${POSTGRES_PASSWORD}@db:5432/flamenet"
FN_RELAY_AUDIENCE: "${FN_RELAY_AUDIENCE:-flamenet-relay}"
# Both are required and have no defaults. A relay that invented its own
# would mint tokens nobody else could verify and silently change the key
# every restart.
FN_ISSUER_PUBLIC_KEY: "${FN_ISSUER_PUBLIC_KEY:?generate an issuer keypair - see .env.example}"
FN_ISSUER_PRIVATE_KEY: "${FN_ISSUER_PRIVATE_KEY:?generate an issuer keypair - see .env.example}"
# Donations are off unless both are set. Card details never reach this
# service: the form posts an amount and the relay redirects to the
# processor's own hosted checkout.
FN_DONATE_PROVIDER: "${FN_DONATE_PROVIDER:-}"
FN_DONATE_SECRET: "${FN_DONATE_SECRET:-}"
# The connected account the donation is charged on, and the publishable
# key the browser mounts the form with. Without the first, the same key
# charges the platform account and Stripe reports no error.
FN_DONATE_ACCOUNT: "${FN_DONATE_ACCOUNT:-}"
FN_DONATE_PUBLISHABLE_KEY: "${FN_DONATE_PUBLISHABLE_KEY:-}"
# Everything else `.env` documents (SMTP, device limits, S3, contact
# addresses, the Android release, and the rest) reaches the relay through
# `env_file` below. Compose does not pass the host environment through to
# a container: without that line a variable set in `.env` and missing
# from this list is read for interpolation and never reaches the relay,
# so the setting silently does nothing while looking configured. That
# happened to the Android release variables the first time they were
# documented, and then to every variable added after them. What is
# listed here wins over the file, which is what makes the derived ones
# above safe.
env_file:
- .env
ports:
# Overridable because 8080 is one of the most commonly occupied ports
# on a machine that already self-hosts things, which is exactly the
# machine this runs on. Set FN_HOST_PORT in .env rather than editing this
# file, so a later `git pull` does not conflict with your change.
- "127.0.0.1:${FN_HOST_PORT:-8080}:8080"
volumes:
# Attachments are files, not rows. Postgres holds everything else.
- attachments:/data/attachments
# No coturn here, deliberately. `docker-compose.prod.yml` and
# `docker-compose.federated.yml` both run one, because calls across symmetric
# NAT and CGNAT need a relay in the middle. This file publishes to 127.0.0.1
# and is for working on the relay: two clients on one machine reach each other
# directly, and host-networked TURN would add forty published UDP ports to buy
# nothing. `/e2e/turn` answering 503 here is correct, not a missing piece.
volumes:
db-data:
attachments: