gendesign/ops/forgejo/docker-compose.yml
bot-backend 635ad2df35
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m38s
CI / backend-tests (pull_request) Successful in 6m32s
chore(forgejo): track compose file with retention/cleanup settings
app.ini on prod has no [cron.archive_cleanup] section and no retention
keys under [actions] — everything ran on Forgejo defaults (archive
cache swept once/24h, no cap on Actions log/artifact age). An external
crawler hitting per-commit archive URLs grew repo-archive cache to
~48GB/145GB before the daily sweep caught up; Caddy now blocks that
path (#3534), but this is the second line of defense if that rule is
ever lifted.

Forgejo isn't part of the automated deploy pipeline and its compose
file only existed on the host (not a git checkout), so there was
nowhere for this config to survive a redeploy or even be reviewed.
Adds a tracked copy at ops/forgejo/docker-compose.yml, alongside the
existing ops/backup.sh and ops/restore.sh host scripts, with:

- [cron.archive_cleanup]: ENABLED/RUN_AT_START=true, SCHEDULE=@every
  1h, OLDER_THAN=1h — hourly sweep instead of daily, 1h grace window.
- [actions] LOG_RETENTION_DAYS=30, ARTIFACT_RETENTION_DAYS=14 — checked
  against .forgejo/workflows and .github/workflows first: no workflow
  uploads/downloads artifacts today, so nothing to break.

Key names verified against the running image (Forgejo 10.0.3) by
extracting Go struct ini-tags from the binary and dry-running
environment-to-ini in a container scratch dir — not from memory, since
a wrong key is silently dropped.

Not applied to prod. Needs manual scp + `up -d --force-recreate
forgejo` per the file's header comment — see PR description.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JY6iWDnGDthdvsMWgK1BMG
2026-09-16 22:30:27 +03:00

81 lines
3.8 KiB
YAML

# Source-of-truth copy of the Forgejo compose file.
#
# Forgejo is NOT part of the automated deploy pipeline (deploy.yml only
# manages /opt/gendesign via `git reset --hard origin/main` on the main and
# obsidian stacks). Forgejo lives separately at /home/gendesign/forgejo on
# the VM and is a plain directory there — NOT a git checkout — so changes
# here do not auto-apply. Sync manually:
#
# scp ops/forgejo/docker-compose.yml gendesign:/home/gendesign/forgejo/docker-compose.yml
# ssh gendesign "cd /home/gendesign/forgejo && docker compose up -d --force-recreate forgejo"
#
# `up -d --force-recreate` (not `restart`) is required: Forgejo generates
# app.ini from the FORGEJO__* env vars via /usr/local/bin/environment-to-ini
# at container start, and `restart` does not re-read `environment:` from a
# changed compose file (see docker-compose pitfall #1 in devops CLAUDE.md).
#
# Config keys verified 2026-09-16 against the running image
# (codeberg.org/forgejo/forgejo:10, Forgejo 10.0.3+gitea-1.22.0) by
# extracting Go struct tags from the binary (`strings` on
# /app/gitea/gitea) and by a dry-run of environment-to-ini in a scratch
# dir inside the container (no prod files touched). Do not re-derive these
# from memory — a wrong key is silently ignored (empty section) and
# creates a false sense of safety.
#
# Dotted section names ([cron.archive_cleanup]) must be encoded as
# `_0x2E_` in the env var per the container's own
# `environment-to-ini --help` (confirmed empirically, see PR description).
services:
forgejo:
image: codeberg.org/forgejo/forgejo:10
container_name: forgejo
restart: unless-stopped
environment:
USER_UID: 1000
USER_GID: 1000
FORGEJO__database__DB_TYPE: postgres
FORGEJO__database__HOST: infra-postgres:5432
FORGEJO__database__NAME: forgejo
FORGEJO__database__USER: forgejo
FORGEJO__database__PASSWD: ${FORGEJO_DB_PASS}
FORGEJO__server__DOMAIN: git.gendsgn.ru
FORGEJO__server__ROOT_URL: https://git.gendsgn.ru/
FORGEJO__server__SSH_PORT: 2222
FORGEJO__server__SSH_LISTEN_PORT: 22
FORGEJO__server__START_SSH_SERVER: "false"
FORGEJO__service__DISABLE_REGISTRATION: "true"
FORGEJO__service__REQUIRE_SIGNIN_VIEW: "false"
FORGEJO__actions__ENABLED: "true"
FORGEJO__actions__DEFAULT_ACTIONS_URL: "github"
# Actions Log/artifact retention — was unset (Forgejo defaults), which
# let CI run logs/artifacts accumulate indefinitely. Artifact
# retention checked against .forgejo/workflows + .github/workflows on
# 2026-09-16: no workflow uploads/downloads artifacts today, so 14d
# cannot break a cross-job dependency. Revisit this comment if a
# workflow starts using actions/upload-artifact.
FORGEJO__actions__LOG_RETENTION_DAYS: "30"
FORGEJO__actions__ARTIFACT_RETENTION_DAYS: "14"
# Repo-archive cache cleanup — was entirely absent (no
# [cron.archive_cleanup] section), so it ran on Forgejo's own default
# schedule (once every 24h, deleting archives older than 24h). That
# let an external crawler hitting /<owner>/<repo>/archive/<ref>
# balloon the cache to ~48GB/145GB disk before the daily sweep caught
# up (see PR #3534, which closed the path in Caddy as the primary
# fix). This is the second line of defense if that Caddy rule is ever
# removed: run hourly, evict anything older than 1h.
FORGEJO__CRON_0x2E_ARCHIVE_CLEANUP__ENABLED: "true"
FORGEJO__CRON_0x2E_ARCHIVE_CLEANUP__RUN_AT_START: "true"
FORGEJO__CRON_0x2E_ARCHIVE_CLEANUP__SCHEDULE: "@every 1h"
FORGEJO__CRON_0x2E_ARCHIVE_CLEANUP__OLDER_THAN: "1h"
FORGEJO__security__INSTALL_LOCK: "true"
volumes:
- ./data/forgejo:/data
ports:
- "2222:22"
networks:
- gendesign_default
networks:
gendesign_default:
external: true
name: gendesign_default