# 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 ///archive/ # 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