3471d40576
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Successful in 1m4s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m27s
The finished-game export now works identically on every platform: the client mints a signed relative URL (game.export_url) carrying its date locale, IANA time zone and localized non-play labels, resolves it against its own origin and hands it to the platform's native download — Telegram downloadFile, VKWebAppDownloadFile, or a plain browser anchor (also the desktop VK iframe). Both artifacts ride the route: the .gcg text (no more clipboard mode, except the legacy pre-8.0 Telegram fallback) and the PNG of the final position. The PNG is rasterized by a new internal 'renderer' sidecar (node:22-slim + skia-canvas + baked Liberation/Noto Color Emoji fonts) executing the SAME ui/src/lib/gameimage.ts the web project unit-tests, bundled at image build time — one renderer, no drift; the browser no longer draws or delivers bytes itself. The backend rebuilds the render payload from the journal + engine.AlphabetTable, verifies the HMAC (10-minute TTL, BACKEND_EXPORT_SIGN_KEY, constant-time, uniform 404s) on its public group, and streams the artifact as a named attachment; the gateway forwards /dl/* behind the per-IP public rate limiter (caddy @gateway matcher extended — the landing catch-all trap). Deploy: renderer service (compose + prod overlay + roll before backend + prod push list), EXPORT_SIGN_KEY env (TEST_/PROD_ secrets), CI runs the sidecar smoke in the ui job. Docs: ARCHITECTURE export-delivery section, FUNCTIONAL(+_ru), UI_DESIGN, TESTING, deploy/README.
70 lines
4.3 KiB
Bash
70 lines
4.3 KiB
Bash
# Environment for deploy/docker-compose.yml. The CI deploy job (ci.yaml) maps the
|
|
# Gitea TEST_-prefixed secrets/variables onto these unprefixed names; the prod
|
|
# deploy maps the PROD_-prefixed set the same way. Copy to deploy/.env for a local run.
|
|
#
|
|
# Full reference (required vs optional, defaults, secret-vs-variable): deploy/README.md.
|
|
|
|
# --- Postgres ---------------------------------------------------------------
|
|
POSTGRES_DB=scrabble
|
|
POSTGRES_USER=scrabble
|
|
POSTGRES_PASSWORD=change-me # required
|
|
|
|
# --- Dictionary -------------------------------------------------------------
|
|
# scrabble-dictionary release tag baked into the image as the SEED dictionary for a
|
|
# FRESH volume (image build-arg; also labels the resident seed version). After first
|
|
# boot the dawg-data volume preserves versions uploaded through the admin console and
|
|
# the active version lives in the DB. On a live volume a changed value is ignored (the
|
|
# recorded .seed_version marker wins — the seed-drift guard); change a running
|
|
# contour's dictionary through /_gm/dictionary (ARCHITECTURE.md §5).
|
|
DICT_VERSION=v1.3.0
|
|
|
|
# --- Logging ----------------------------------------------------------------
|
|
LOG_LEVEL=info
|
|
|
|
# --- Finished-game export ----------------------------------------------------
|
|
# HMAC key signing the public export download URLs (/dl/*). Required; generate a
|
|
# real contour value with `openssl rand -base64 32` (Gitea TEST_/PROD_EXPORT_SIGN_KEY).
|
|
EXPORT_SIGN_KEY=dev-export-sign-key
|
|
|
|
# --- Edge / caddy -----------------------------------------------------------
|
|
# Test: ":80" (the host caddy terminates TLS and forwards to scrabble:80 on the
|
|
# external `edge` network). Prod: a domain so caddy does its own ACME.
|
|
CADDY_SITE_ADDRESS=:80
|
|
GM_BASICAUTH_USER=gm
|
|
GM_BASICAUTH_HASH= # required; `caddy hash-password` bcrypt hash
|
|
|
|
# --- UI build args (baked into the gateway image) ---------------------------
|
|
VITE_TELEGRAM_BOT_ID=
|
|
VITE_TELEGRAM_LINK= # friend-invite Mini App link (full URL, e.g. https://t.me/<bot>/<app>)
|
|
VITE_TELEGRAM_GAME_CHANNEL_NAME= # landing "Play in Telegram" link, the bot's game channel
|
|
VITE_VK_APP_LINK= # landing "Play on VK" link (full URL, https://vk.com/app<id>)
|
|
VITE_GATEWAY_URL=
|
|
|
|
# --- Grafana ----------------------------------------------------------------
|
|
GRAFANA_ROOT_URL=/_gm/grafana/ # set the full https URL behind a real domain
|
|
GRAFANA_ADMIN_PASSWORD=admin
|
|
|
|
# --- Telegram validator + bot -----------------------------------------------
|
|
# The token is shared: the validator uses it as the HMAC secret, the bot for the
|
|
# Bot API. The bot-link wiring (validator/relay/mTLS addresses) is hard-wired in
|
|
# docker-compose.yml; the mTLS material is NOT here — run `deploy/gen-certs.sh`
|
|
# (writes deploy/certs/, gitignored) before `docker compose up`.
|
|
AWG_CONF= # required; AmneziaWG sidecar config (the bot's Telegram egress)
|
|
TELEGRAM_BOT_TOKEN= # required
|
|
TELEGRAM_GAME_CHANNEL_ID=
|
|
TELEGRAM_CHAT_ID= # moderated discussion chat (channel's linked group); empty disables gating
|
|
TELEGRAM_SUPPORT_CHAT_ID= # private forum supergroup for the support relay (topic per user); empty disables it
|
|
TELEGRAM_PROMO_BOT_TOKEN= # optional standalone promo bot token; empty disables it
|
|
TELEGRAM_BOT_USERNAME= # main bot @username without the @ (promo message); required when the promo token is set
|
|
TELEGRAM_BOT_LINK= # main bot Mini App link for the promo button (reuse VITE_TELEGRAM_LINK); required when the promo token is set
|
|
TELEGRAM_PROMO_START_PARAM= # promo button startapp payload — a variant-seed deep link (default verudit_ru-scrabble_en) adding English Scrabble for new users; empty forwards the user's /start payload
|
|
TELEGRAM_MINIAPP_URL= # required
|
|
TELEGRAM_TEST_ENV=false
|
|
TELEGRAM_API_BASE_URL=
|
|
|
|
# --- VK Mini App ------------------------------------------------------------
|
|
# The VK app's "protected key" (client_secret): the gateway verifies the Mini App
|
|
# launch-parameter signature in-process under it (a pure offline HMAC, no VK API call).
|
|
# Empty disables the VK auth path (auth.vk). Set from the Gitea TEST_/PROD_ secret.
|
|
GATEWAY_VK_APP_SECRET=
|