Files
windy-git/docker-compose.yml
Grant Whitmer a68261a563 G1: Veron 1 host live behind Cloudflare Tunnel
app.windygit.com / api.windygit.com / models.windygit.com are serving over
HTTPS with ZERO inbound ports open on Grant's network.

  - tunnel 4e856c5d, 4 registered edge connections, systemd-managed and bounded
  - three proxied single-level CNAMEs (Free Universal SSL covers them; a
    two-level name would need ACM and would die in the TLS handshake)
  - services bound to 127.0.0.1 with configurable host ports — Veron 1 is
    Grant's workstation and 3000/3300 belong to other projects
  - docs/RUNBOOK-VERON.md

I-12 PROVEN IN PRODUCTION: /version reports source=baked with a sha equal to
the deployed HEAD.

Also fixed: the tunnel health probe targeted localhost from inside a container,
so it was permanently red. A check that is always red is as useless as one that
is always green — it is how a fleet canary goes 37 days dead unnoticed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 14:34:18 -04:00

69 lines
2.9 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}}
# cloudflared runs on the host, not in this network. Without this the tunnel
# probe is permanently red and stops meaning anything.
extra_hosts: ["host.docker.internal:host-gateway"]
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__repository__DEFAULT_BRANCH: main
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"
GITEA__lfs__PATH: /data/lfs
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
volumes: ["./data/pg:/var/lib/postgresql/data"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U windygit"]
interval: 5s
retries: 10
restart: unless-stopped