infra/forgejo/forgejo-compose.yml
s8n 09d80a63f6 init: nullstone deploys + runbooks + audits
Sourced from previous audits + agent-wave outputs (2026-05-05):
  AUDIT-2026-05-05.md           — 5-agent stack synthesis
  forgejo/DEPLOY.md             — git.s8n.ru deploy runbook
  forgejo/forgejo-compose.yml   — production compose
  forgejo/runner-compose.yml    — forgejo-runner
  forgejo/migration-report-...  — GH→Forgejo migration audit (6/6 green)
  runbooks/MIGRATION-...        — nullstone→cobblestone runbook
  runbooks/DE-DECISION-...      — keep-vs-strip DE on cobblestone
  repos/REPO-AUDIT-2026-05-05.md — repo trees + ownership
2026-05-06 10:02:28 +01:00

68 lines
3.1 KiB
YAML

# Forgejo — self-hosted git + CI for veilor-org
# Deploy path on nullstone: /opt/docker/forgejo/
# Domain: git.s8n.ru
#
# Why: GH Actions free-tier minute quota was hammering veilor-os builds
# (5+ ISO builds = 150min, repeatable runner-shortage failures). Forgejo
# Actions takes the same `build-iso.yml` workflow unmodified and runs it
# on hardware we own. Bonus: full git host independence.
#
# Design notes:
# - Image pinned by tag, not digest, until we automate pinning. Forgejo
# releases roughly every 1-2 months; bump in this file.
# - SSH on host port 222 (host 22 is sshd for nullstone admin). Forgejo's
# internal ssh server reads /var/lib/forgejo/.ssh/authorized_keys, no
# pam, no sudo.
# - HTTP-only inside the proxy network; Traefik terminates TLS at the edge
# via the existing letsencrypt resolver (Gandi LiveDNS DNS-01).
# - `userns: host` matches the nullstone Docker convention so volume
# ownership maps cleanly to host UID 1000 (memory: project_nullstone_docker_userns.md).
services:
forgejo:
image: codeberg.org/forgejo/forgejo:9-rootless
container_name: forgejo
restart: unless-stopped
user: "1000:1000"
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__database__DB_TYPE=sqlite3
- FORGEJO__server__DOMAIN=git.s8n.ru
- FORGEJO__server__ROOT_URL=https://git.s8n.ru/
- FORGEJO__server__SSH_DOMAIN=git.s8n.ru
- FORGEJO__server__SSH_PORT=222 # public-facing SSH on host:222
- FORGEJO__server__SSH_LISTEN_PORT=2222 # container-internal listen port
- FORGEJO__server__START_SSH_SERVER=true
- FORGEJO__server__OFFLINE_MODE=false
- FORGEJO__security__INSTALL_LOCK=true # skip /install wizard; use envs above
- FORGEJO__service__DISABLE_REGISTRATION=true # invite-only; no public signup
- FORGEJO__service__REQUIRE_SIGNIN_VIEW=false # public repos viewable
- FORGEJO__actions__ENABLED=true # turns on Forgejo Actions
- FORGEJO__actions__DEFAULT_ACTIONS_URL=github # so `uses: actions/checkout@v4` resolves
- FORGEJO__webhook__ALLOWED_HOST_LIST=* # for GH mirroring webhooks
- FORGEJO__log__LEVEL=Info
# Email (optional; SMTP via authentik or local relay)
# - FORGEJO__mailer__ENABLED=false
volumes:
- /home/docker/forgejo/data:/var/lib/gitea
- /home/docker/forgejo/config:/etc/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "0.0.0.0:222:2222/tcp" # public SSH for git-over-ssh (port 22 is host sshd)
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.forgejo.rule=Host(`git.s8n.ru`)"
- "traefik.http.routers.forgejo.entrypoints=websecure"
- "traefik.http.routers.forgejo.tls=true"
- "traefik.http.routers.forgejo.tls.certresolver=letsencrypt"
- "traefik.http.routers.forgejo.middlewares=security-headers@file,rate-limit@file,no-guest@file"
- "traefik.http.services.forgejo.loadbalancer.server.port=3000"
networks:
proxy:
external: true