feat(forgejo): Git self-host en miroir de GitHub (git.funklab.online, SSO Authentik) (#96)

- k8s/apps/forgejo : deployment (image forgejo:11, config par env), service, PVC nfs,
  IngressRoute interne (git.lab.local) + publique (git.funklab.online + middlewares
  security-headers/ratelimit), Application ArgoCD (ns ai, recurse)
- base PostgreSQL `forgejo` sur storage-01 (rôle postgresql)
- vault : vault_pg_forgejo_password + vault_forgejo_oauth_client_secret
- doc admin/k8s/forgejo.md (archi, OIDC, création du miroir, pièges) + index + CLAUDE.md

GitHub reste la source de vérité (pull-mirror lecture seule) — ArgoCD inchangé.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ALI YESILKAYA 2026-07-07 23:20:33 +02:00 committed by GitHub
parent fe0aa89ffa
commit 224c06041e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 498 additions and 163 deletions

View file

@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgejo
namespace: ai
spec:
replicas: 1
strategy:
type: Recreate # PVC RWO : pas de deux pods qui montent /data en parallèle
selector:
matchLabels:
app: forgejo
template:
metadata:
labels:
app: forgejo
spec:
containers:
- name: forgejo
image: codeberg.org/forgejo/forgejo:11
ports:
- containerPort: 3000
name: http
env:
# --- Base PostgreSQL sur storage-01 (hors cluster), pattern Ghostfolio/n8n ---
- name: FORGEJO__database__DB_TYPE
value: "postgres"
- name: FORGEJO__database__HOST
value: "192.168.10.1:5432"
- name: FORGEJO__database__NAME
value: "forgejo"
- name: FORGEJO__database__USER
value: "forgejo"
- name: FORGEJO__database__PASSWD
valueFrom:
secretKeyRef:
name: forgejo-secret
key: pg-password
# --- Serveur : URL canonique = domaine HTTPS (split-horizon dnsmasq en LAN) ---
- name: FORGEJO__server__DOMAIN
value: "git.funklab.online"
- name: FORGEJO__server__ROOT_URL
value: "https://git.funklab.online/"
- name: FORGEJO__server__HTTP_PORT
value: "3000"
# Pas de git-over-SSH : miroir + consultation en HTTPS uniquement (aucun
# port 22 supplémentaire exposé). Le clone/pull passe par HTTPS.
- name: FORGEJO__server__DISABLE_SSH
value: "true"
# --- Service : inscription fermée → connexion via SSO Authentik uniquement ---
- name: FORGEJO__service__DISABLE_REGISTRATION
value: "true"
# Autorise la création de compte au 1er login OIDC (source externe)
- name: FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION
value: "true"
- name: FORGEJO__service__ENABLE_BASIC_AUTHENTICATION
value: "true" # clone HTTPS avec token perso
# --- Sécurité : install déjà verrouillée (config par env), clé stable ---
- name: FORGEJO__security__INSTALL_LOCK
value: "true"
- name: FORGEJO__security__SECRET_KEY
valueFrom:
secretKeyRef:
name: forgejo-secret
key: secret-key
- name: FORGEJO__migrations__ALLOWED_DOMAINS
value: "github.com" # miroir : ne tire que depuis GitHub
- name: USER_UID
value: "1000"
- name: USER_GID
value: "1000"
- name: TZ
value: "Europe/Paris"
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "1000m"
memory: 768Mi
readinessProbe:
httpGet:
path: /api/healthz
port: 3000
initialDelaySeconds: 20
periodSeconds: 15
livenessProbe:
httpGet:
path: /api/healthz
port: 3000
initialDelaySeconds: 60
periodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: forgejo-data

View file

@ -0,0 +1,24 @@
# Accès public HTTPS — git.funklab.online (cert Let's Encrypt auto).
# Hérite du durcissement edge : middlewares security-headers + ratelimit (ns infra).
# Route interne git.lab.local conservée (ingress.yaml).
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: forgejo-public
namespace: ai
spec:
entryPoints:
- websecure
routes:
- match: Host(`git.funklab.online`)
kind: Rule
middlewares:
- name: security-headers
namespace: infra
- name: ratelimit
namespace: infra
services:
- name: forgejo
port: 3000
tls:
certResolver: letsencrypt

View file

@ -0,0 +1,15 @@
# Accès interne LAN — git.lab.local (HTTP, via dnsmasq wildcard → Traefik).
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: forgejo
namespace: ai
spec:
entryPoints:
- web
routes:
- match: Host(`git.lab.local`)
kind: Rule
services:
- name: forgejo
port: 3000

15
k8s/apps/forgejo/pvc.yaml Normal file
View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: forgejo-data
namespace: ai
spec:
# /data : dépôts git (miroir de GitHub), avatars, LFS, app.ini (config générée +
# INTERNAL_TOKEN persistant). La base relationnelle est sur storage-01 (PostgreSQL),
# seul le contenu git vit ici.
accessModes:
- ReadWriteOnce
storageClassName: nfs
resources:
requests:
storage: 10Gi

View file

@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: forgejo
namespace: ai
spec:
selector:
app: forgejo
ports:
- port: 3000
targetPort: 3000