5 Commits

Author SHA1 Message Date
Ilia Denisov 0a0a9e5a8d fix(deploy): wire the Robokassa direct rail into the prod deploy + rollback
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 27s
CI / ui (pull_request) Successful in 1m11s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m54s
The Robokassa credentials reached only the test contour (ci.yaml → TEST_
secrets). The prod-deploy / prod-rollback workflows and write-prod-env.sh
never rendered BACKEND_ROBOKASSA_*, so on prod the shop login was empty and
the direct RUB rail stayed disabled — the PROD_BACKEND_ROBOKASSA_* secrets
went nowhere.

Export the shop login + Password1/Password2 (secrets) and a
BACKEND_ROBOKASSA_TEST flag (a variable, so go-live is a flag flip not a
secret rotation) from both prod workflows, and emit the four ROBOKASSA_*
vars from write-prod-env.sh (the shared deploy/rollback env renderer) so a
rollback keeps the rail up. The compose already maps ROBOKASSA_* →
BACKEND_ROBOKASSA_*. Document the new secrets/variable in the deploy README
and .env.example. Password3 (Robokassa's JWT-invoice API) is unused.
2026-07-10 11:59:20 +02:00
Ilia Denisov a58f2ce0e4 fix(deploy): support a non-standard S3 port for the pgBackRest endpoint
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 1s
CI / deploy (pull_request) Successful in 1m43s
The S3 endpoint is a host only; some providers publish a separate, non-443
port. Add an optional PGBACKREST_S3_PORT (default 443) alongside the endpoint
host, wired through the prod overlay, write-prod-env.sh and both prod workflows,
and clarify in the docs that the endpoint variable takes the host alone.
2026-07-09 01:14:05 +02:00
Ilia Denisov e922f5f3b9 feat(deploy): continuous WAL archiving to S3 for point-in-time recovery
CI / changes (pull_request) Successful in 4s
CI / unit (pull_request) Successful in 12s
CI / integration (pull_request) Successful in 24s
CI / ui (pull_request) Successful in 1m9s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s
Add pgBackRest-based PITR for the production database, shipped disarmed
(archive_mode and the base-backup timer gated off) so it stays inert until the
operator arms it before real payments — an un-armed deploy cannot pile WAL onto
the disk.

- Postgres now builds from a thin image carrying pgBackRest (archive_command runs
  in-process); the prod overlay wires an encrypted (AES-256-CBC), path-style S3
  repository with 30-day retention and a daily full base-backup systemd timer.
- Repository config/secrets flow through the PROD_PGBACKREST_* Gitea set and
  write-prod-env.sh; prod-rollback re-renders the same env so a rollback cannot
  disarm archiving.
- Grafana alerts watch pg_stat_archiver (failing / stalled), absent-safe on the
  test contour, which never archives.
- Fix the pre-migration pg_dump to snapshot the whole database (was backend-only,
  silently excluding payments).
- Document the PITR runbook, the arming sequence and the restore drill in
  deploy/README.md; record the measured cost/perf assessment.
2026-07-09 00:58:04 +02:00
Ilia Denisov a0021d1994 feat(gateway): wire GATEWAY_HONEYTOKEN through the deploy
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 20s
CI / ui (pull_request) Successful in 1m6s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m44s
The planted honeytoken bearer trap already existed in the gateway + compose, but
no workflow fed GATEWAY_HONEYTOKEN, so it was always empty (inert). Wire the
per-contour TEST_/PROD_GATEWAY_HONEYTOKEN secret into the ci deploy, prod-deploy
and prod-rollback env (the prod path via the shared deploy/write-prod-env.sh),
document it (deploy/README + .env.example), and fix the stale compose comment.

Empty secret = trap off (no ":?" guard), so a deploy is safe before the operator
sets the value + plants the bait. On prod (IP ban on) presenting it earns a 24h
ban + alarm; on test (ban off) it logs + a ban metric.

GF_SMTP_ENABLED is enabled separately via the TEST_/PROD_GF_SMTP_ENABLED Gitea
variables (=true) — no code change.
2026-07-03 21:36:23 +02:00
Ilia Denisov 7f85362288 chore(deploy): dedupe & regroup Gitea CI variables/secrets
CI / changes (pull_request) Successful in 2s
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 1m44s
Collapse identical TEST_/PROD_ pairs to single unprefixed Gitea entries, derive
the public URLs from PUBLIC_BASE_URL at deploy time, and share the prod env.sh
renderer between deploy and rollback.

- Collapse to one unprefixed variable: DICT_VERSION, SMTP_RELAY_HOST/PORT/TLS,
  GRAFANA_SMTP_PORT, VITE_VK_APP_LINK, VITE_VK_APP_ID (one Selectel relay + one
  pair of VK apps serve every contour). Secrets collapsed by the owner:
  SMTP_RELAY_USER/PASS, GATEWAY_VK_APP_SECRET, GATEWAY_VK_ID_CLIENT_SECRET.
- Derive at deploy from PUBLIC_BASE_URL (no longer stored): TELEGRAM_MINIAPP_URL,
  GRAFANA_ROOT_URL, VITE_VK_ID_REDIRECT_URL. Removes the prod/test asymmetry and
  fills the missing test VITE_VK_APP_ID (VK web login was half-configured on test).
- Extract deploy/write-prod-env.sh + write-prod-bot-env.sh, shared by prod-deploy
  and prod-rollback so the two cannot drift: a rollback now re-renders the FULL
  runtime env (email / VK login / Grafana alerts previously went dark after a
  rollback) and passes TELEGRAM_SUPPORT_CHAT_ID.
- Single-source DICT_VERSION (CI env + both deploys), fix the v1.3.0/v1.3.1 drift in
  .env.example/README, correct the misleading honeytoken/abuse-ban compose comment,
  and rewrite the deploy/README variable list (+ the previously undocumented
  GATEWAY_VK_APP_SECRET and TELEGRAM_SUPPORT_CHAT_ID).

The Gitea variables are reworked via the API; the stale TEST_/PROD_ entries are
deleted after the test contour goes green.
2026-07-03 21:07:07 +02:00