# Gitea K8s Migration Plan (2026-07-13) Session where the user decided to migrate Gitea from LXC CT108 to RKE2 K8s. ## Current State (CT108) - Host: proxmox6, LXC container - Gitea binary (not Docker), SQLite (4.7 MB) - 23 repos (160 MB), 5 orgs/users (dominik, clawdia, codecamp-n, pm-infra, d.schoen) - Config: `/etc/gitea/app.ini`, data: `/var/lib/gitea/data/` - RAM: ~142 MB RSS, Disk: 1.3 GB / 7.8 GB ## Key Decisions ### 1. Galera over CNPG (user-directed) User instinctively preferred Galera, then asked for evaluation. After comparison, Galera won decisively: - HA: Galera has 3 nodes + MaxScale. CNPG plan was 1 instance = no HA. - Resources: Galera = 0 new. CNPG = 512Mi + 10Gi. - MySQL is Gitea's native DB — best-tested combination. - SQLite→MySQL migration via Gitea Migration API (no schema conversion). ### 2. Gitea Migration API over manual SQLite dump The Gitea Migration API (`POST /api/v1/repos/migrate`) eliminates the hardest task entirely. One call per repo brings: - Git data (clone) - Issues + labels + milestones - Pull requests - Releases - Wiki No `pgloader`, no `sed` on SQLite dumps, no schema conversion. ### 3. External URL: git.schoen.codes User specified `git.schoen.codes` as the new external URL (not `git.familie-schoen.com`). ## Plan Structure (10 Tasks) 1. Create 1Password items (gitea-db, gitea-security) 2. Create database on Galera via MaxScale VIP 3. Scaffold iac-homelab directory structure + ArgoCD app manifest 4. Create ExternalSecrets (DB creds + security tokens) 5. Create Gitea Helm release values (Galera DB, PVC, Ingress) 6. Verify K8s Gitea reachable + DB connected 7. Migrate repos + metadata via Gitea Migration API 8. DNS cutover (git.schoen.codes → K8s LoadBalancer IP) 9. Update ArgoCD source URL (chicken-egg cutover) 10. Shutdown CT108 after 7-day stability window ## Resource Footprint | Component | CPU req | RAM req | Storage | |-----------|---------|---------|---------| | Gitea pod | 100m | 256Mi | 10Gi (HDD) | | Total | 100m | 256Mi | 10Gi | Previous (CT108): 1 core, 1 GB RAM, 8 GB disk → K8s footprint smaller. ## iac-homelab Repo Structure ``` clusters/main/ ├── apps/gitea.yaml # ArgoCD Application (sync-wave 2) ├── gitea/ │ ├── namespace.yaml │ ├── external-secrets.yaml # gitea-db + gitea-security (sync-wave 0) │ ├── values.yaml # HelmChart CR (sync-wave 2) │ └── README.md └── docs/plans/2026-07-13-gitea-k8s-migration.md ``` ## Established Patterns Applied - ArgoCD App manifest → `clusters/main/apps/{name}.yaml` with sync-waves - ExternalSecrets → `external-secrets.io/v1`, ClusterSecretStore `onepassword-store` - StorageClasses: `ceph-flash` (SSD) for DB, `ceph-hdd-replica` (HDD) for repo data - Traefik ingress with TLS - `CreateNamespace=true` in ArgoCD syncOptions