Hearth is the infrastructure home for the letemcook ecosystem. Ported from coherence-mcp/infra: - Terraform modules (VPC, EKS, IAM, NLB, S3, storage) - Kubernetes manifests (Forgejo, ingress, cert-manager, karpenter) - Deployment scripts (phased rollout) Status: Not deployed. EKS cluster needs to be provisioned. Next steps: 1. Bootstrap terraform backend 2. Deploy phase 1 (foundation) 3. Deploy phase 2 (core services including Forgejo) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
263 lines
8.1 KiB
YAML
263 lines
8.1 KiB
YAML
# Forgejo Deployment
|
|
# RFC 0040: Self-Hosted Core Services
|
|
# RFC 0049: Service Database Unification - CockroachDB backend
|
|
# ADR 0004: Set It and Forget It - auto-scaling via HPA
|
|
# ADR 0005: Full-stack self-hosting
|
|
#
|
|
# Spike 2026-01-19: Forgejo v9 works with CockroachDB after setting
|
|
# sql.defaults.serial_normalization = 'sql_sequence' to fix XORM SERIAL handling.
|
|
# Requires extended startup probes for initial 230-table migration.
|
|
#
|
|
# Integrated with Keycloak SSO
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: forgejo
|
|
namespace: forgejo
|
|
labels:
|
|
app.kubernetes.io/name: forgejo
|
|
app.kubernetes.io/part-of: core-services
|
|
spec:
|
|
replicas: 1 # Single replica due to ReadWriteOnce storage; HA requires EFS or Redis queue
|
|
selector:
|
|
matchLabels:
|
|
app: forgejo
|
|
strategy:
|
|
type: Recreate # Required for single replica with RWO storage (LevelDB queue lock)
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: forgejo
|
|
app.kubernetes.io/name: forgejo
|
|
annotations:
|
|
prometheus.io/scrape: "true"
|
|
prometheus.io/port: "3000"
|
|
prometheus.io/path: "/metrics"
|
|
spec:
|
|
serviceAccountName: forgejo
|
|
terminationGracePeriodSeconds: 60
|
|
|
|
# Spread pods across AZs for HA
|
|
affinity:
|
|
podAntiAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 100
|
|
podAffinityTerm:
|
|
labelSelector:
|
|
matchLabels:
|
|
app: forgejo
|
|
topologyKey: topology.kubernetes.io/zone
|
|
|
|
# Forgejo needs elevated permissions for initial setup (chown, su-exec)
|
|
# After initial setup, consider using a custom image with pre-set permissions
|
|
securityContext:
|
|
fsGroup: 1000
|
|
runAsUser: 0
|
|
|
|
initContainers:
|
|
# Wait for CockroachDB to be ready
|
|
- name: wait-for-db
|
|
image: postgres:16-alpine
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
until pg_isready -h cockroachdb-public.cockroachdb.svc.cluster.local -p 26257; do
|
|
echo "Waiting for CockroachDB..."
|
|
sleep 5
|
|
done
|
|
echo "CockroachDB is ready!"
|
|
# Fix ssh directory permissions for git user
|
|
- name: fix-permissions
|
|
image: alpine:3.19
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
# Ensure ssh directory exists with correct permissions
|
|
mkdir -p /data/git/.ssh
|
|
chown -R 1000:1000 /data/git
|
|
chmod 770 /data/git/.ssh
|
|
echo "Permissions fixed"
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /data
|
|
|
|
containers:
|
|
- name: forgejo
|
|
image: codeberg.org/forgejo/forgejo:9
|
|
imagePullPolicy: IfNotPresent
|
|
|
|
env:
|
|
# Database configuration (CockroachDB)
|
|
- name: FORGEJO__database__DB_TYPE
|
|
value: "postgres"
|
|
- name: FORGEJO__database__HOST
|
|
value: "cockroachdb-public.cockroachdb.svc.cluster.local:26257"
|
|
- name: FORGEJO__database__NAME
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-cockroachdb
|
|
key: database
|
|
- name: FORGEJO__database__USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-cockroachdb
|
|
key: username
|
|
- name: FORGEJO__database__PASSWD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-cockroachdb
|
|
key: password
|
|
- name: FORGEJO__database__SSL_MODE
|
|
value: "require"
|
|
- name: FORGEJO__database__CHARSET
|
|
value: "utf8"
|
|
|
|
# Server configuration
|
|
- name: FORGEJO__server__DOMAIN
|
|
value: "git.beyondtheuniverse.superviber.com"
|
|
- name: FORGEJO__server__ROOT_URL
|
|
value: "https://git.beyondtheuniverse.superviber.com"
|
|
- name: FORGEJO__server__SSH_DOMAIN
|
|
value: "git.beyondtheuniverse.superviber.com"
|
|
- name: FORGEJO__server__SSH_PORT
|
|
value: "22"
|
|
- name: FORGEJO__server__LFS_START_SERVER
|
|
value: "true"
|
|
- name: FORGEJO__server__OFFLINE_MODE
|
|
value: "false"
|
|
|
|
# Security settings
|
|
- name: FORGEJO__security__INSTALL_LOCK
|
|
value: "true"
|
|
- name: FORGEJO__security__SECRET_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-secrets
|
|
key: secret-key
|
|
- name: FORGEJO__security__INTERNAL_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-secrets
|
|
key: internal-token
|
|
|
|
# OAuth2 configuration (Keycloak SSO)
|
|
- name: FORGEJO__oauth2__ENABLED
|
|
value: "true"
|
|
- name: FORGEJO__oauth2__JWT_SECRET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-oauth
|
|
key: jwt-secret
|
|
|
|
# Session configuration (for HA)
|
|
- name: FORGEJO__session__PROVIDER
|
|
value: "db"
|
|
- name: FORGEJO__session__PROVIDER_CONFIG
|
|
value: ""
|
|
|
|
# Cache configuration
|
|
- name: FORGEJO__cache__ENABLED
|
|
value: "true"
|
|
- name: FORGEJO__cache__ADAPTER
|
|
value: "memory"
|
|
|
|
# Queue configuration
|
|
- name: FORGEJO__queue__TYPE
|
|
value: "level"
|
|
- name: FORGEJO__queue__DATADIR
|
|
value: "/data/queues"
|
|
|
|
# Repository settings
|
|
- name: FORGEJO__repository__ROOT
|
|
value: "/data/git/repositories"
|
|
- name: FORGEJO__repository__DEFAULT_BRANCH
|
|
value: "main"
|
|
|
|
# LFS settings
|
|
- name: FORGEJO__lfs__PATH
|
|
value: "/data/lfs"
|
|
|
|
# Logging
|
|
- name: FORGEJO__log__MODE
|
|
value: "console"
|
|
- name: FORGEJO__log__LEVEL
|
|
value: "Info"
|
|
|
|
# Metrics
|
|
- name: FORGEJO__metrics__ENABLED
|
|
value: "true"
|
|
- name: FORGEJO__metrics__TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: forgejo-secrets
|
|
key: metrics-token
|
|
|
|
# Service settings
|
|
- name: FORGEJO__service__DISABLE_REGISTRATION
|
|
value: "true"
|
|
- name: FORGEJO__service__REQUIRE_SIGNIN_VIEW
|
|
value: "false"
|
|
|
|
ports:
|
|
- name: http
|
|
containerPort: 3000
|
|
protocol: TCP
|
|
- name: ssh
|
|
containerPort: 22
|
|
protocol: TCP
|
|
|
|
resources:
|
|
requests:
|
|
cpu: 200m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 1000m
|
|
memory: 1Gi
|
|
|
|
# Forgejo needs CHOWN, SETGID, SETUID capabilities for initial setup
|
|
securityContext:
|
|
capabilities:
|
|
add:
|
|
- CHOWN
|
|
- SETGID
|
|
- SETUID
|
|
- FOWNER
|
|
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /data
|
|
|
|
# Health probes - extended for CockroachDB migration time
|
|
startupProbe:
|
|
httpGet:
|
|
path: /api/healthz
|
|
port: 3000
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 60 # Allow up to 10 minutes for initial migration
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /api/healthz
|
|
port: 3000
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /api/healthz
|
|
port: 3000
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 3
|
|
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: forgejo-data
|