101 lines
4.8 KiB
YAML
101 lines
4.8 KiB
YAML
# G0.5 — committed, secrets stripped.
|
|
#
|
|
# Three compose files that wire production to its databases currently exist in
|
|
# exactly one place on earth (SOTU section 5.6.3): windy-pro's postgres override,
|
|
# Mind's WireGuard override, and WindyCloud's kit0 override — the last of which
|
|
# had to be reconstructed after an `rsync --delete` ate it once. This cell will
|
|
# not add a fourth. Real values come from .env, which is gitignored.
|
|
|
|
name: windy-git
|
|
|
|
services:
|
|
api:
|
|
build:
|
|
context: .
|
|
args:
|
|
# I-12: baked at build time. A runtime COMMIT_SHA override is ignored.
|
|
COMMIT_SHA: ${COMMIT_SHA_BUILD:-}
|
|
BUILT_AT: ${BUILT_AT:-}
|
|
env_file: [.env]
|
|
environment:
|
|
DATABASE_URL: postgresql+asyncpg://windygit:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}@db:5432/windygit
|
|
GITEA_BASE_URL: http://gitea:3000
|
|
# Loopback ONLY. cloudflared runs on the host and reaches us over 127.0.0.1;
|
|
# nothing needs to be reachable from the LAN, let alone the internet (G1.6).
|
|
ports: ["127.0.0.1:${API_PORT:-8600}:8600"]
|
|
depends_on: {db: {condition: service_healthy}}
|
|
restart: unless-stopped
|
|
|
|
gitea:
|
|
# G2.1 — PIN AN EXACT VERSION. Never `latest`. Record it in SUBSTRATE.md.
|
|
image: docker.io/gitea/gitea:1.24.6
|
|
environment:
|
|
GITEA__database__DB_TYPE: postgres
|
|
GITEA__database__HOST: db:5432
|
|
GITEA__database__NAME: gitea
|
|
GITEA__database__USER: gitea
|
|
GITEA__database__PASSWD: ${GITEA_DB_PASSWORD:?set GITEA_DB_PASSWORD}
|
|
GITEA__database__SSL_MODE: disable
|
|
GITEA__repository__DEFAULT_BRANCH: main
|
|
# Auto-install: no wizard, no half-configured box waiting on a human.
|
|
GITEA__security__INSTALL_LOCK: "true"
|
|
GITEA__security__SECRET_KEY: ${GITEA_SECRET_KEY:?set GITEA_SECRET_KEY}
|
|
GITEA__server__DOMAIN: ${GITEA_DOMAIN:-app.windygit.com}
|
|
# G6.2 — SSH access is deferred to R1. The tunnel does HTTPS cleanly and
|
|
# no v0 user needs SSH. Recorded as deferred, not forgotten.
|
|
GITEA__server__DISABLE_SSH: "true"
|
|
# Setting the LFS storage backend does NOT turn LFS on. Without this the
|
|
# batch endpoint 404s and the client reports "Repository or object not
|
|
# found", which reads like a permissions problem and is not one.
|
|
GITEA__server__LFS_START_SERVER: "true"
|
|
# G7.1 — CI on our own hardware. This is the whole verification payoff.
|
|
GITEA__actions__ENABLED: "true"
|
|
# D-9 vocabulary law reaches the product name itself.
|
|
GITEA__DEFAULT__APP_NAME: Windy Git
|
|
GITEA__DEFAULT__APP_SLOGAN: Your work, every version, and agents as citizens.
|
|
GITEA__server__ROOT_URL: ${GITEA_ROOT_URL:-http://localhost:3000/}
|
|
# G2.2 — OIDC only. No local password login, no self-registration.
|
|
GITEA__service__DISABLE_REGISTRATION: "true"
|
|
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true"
|
|
# G4.3 — heavy bytes to R2 at ZERO egress. Git object databases stay on
|
|
# local NVMe (I-3); this covers LFS, attachments, packages, avatars and
|
|
# Actions artifacts, which is where GitHub's painful bills actually come
|
|
# from and where R2's free egress is a structural, permanent advantage.
|
|
GITEA__storage__STORAGE_TYPE: minio
|
|
GITEA__storage__MINIO_ENDPOINT: ${R2_ACCOUNT_ID}.r2.cloudflarestorage.com
|
|
GITEA__storage__MINIO_ACCESS_KEY_ID: ${R2_ACCESS_KEY_ID}
|
|
GITEA__storage__MINIO_SECRET_ACCESS_KEY: ${R2_SECRET_ACCESS_KEY}
|
|
GITEA__storage__MINIO_BUCKET: ${R2_BUCKET_LFS:-windy-git-lfs}
|
|
GITEA__storage__MINIO_LOCATION: auto
|
|
GITEA__storage__MINIO_USE_SSL: "true"
|
|
# ⚠️ THE R2 TRAP. R2 rejects the checksum algorithm S3 clients send by
|
|
# default; without this, uploads fail with an opaque checksum error that
|
|
# reads like a credential problem and is not one.
|
|
GITEA__storage__MINIO_CHECKSUM_ALGORITHM: md5
|
|
GITEA__lfs__STORAGE_TYPE: minio
|
|
volumes:
|
|
# I-3: git object databases on a POSIX filesystem. Never object storage.
|
|
- ${GIT_DATA_ROOT:-./data/gitea}:/data
|
|
# Loopback only, and the host port is configurable: Veron 1 is Grant's
|
|
# workstation and already has other projects on 3000 (a node dev server) and
|
|
# 3300 (nginx). A deploy must never fight a resident process for a port.
|
|
ports: ["127.0.0.1:${GITEA_PORT:-3080}:3000"]
|
|
depends_on: {db: {condition: service_healthy}}
|
|
restart: unless-stopped
|
|
|
|
db:
|
|
image: docker.io/library/postgres:16-alpine
|
|
environment:
|
|
POSTGRES_USER: windygit
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}
|
|
POSTGRES_DB: windygit
|
|
GITEA_DB_PASSWORD: ${GITEA_DB_PASSWORD:?set GITEA_DB_PASSWORD}
|
|
volumes:
|
|
- "./data/pg:/var/lib/postgresql/data"
|
|
- "./deploy/postgres:/docker-entrypoint-initdb.d:ro"
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U windygit"]
|
|
interval: 5s
|
|
retries: 10
|
|
restart: unless-stopped
|