wiki-vault/Sources/Homelab/gitea-migration-to-pve.md
2026-05-23 22:38:29 +00:00

6.5 KiB

created path project tags type
2026-05-23 Sources/Homelab gitea-migration-to-pve
git
proxmox
lovebug
pbs
traefik
project-plan

Goal

Relocate Gitea so its placement matches what it has actually become: critical homelab/dev infrastructure, not a service incidentally hosted on the PBS business server. Establish a two-instance architecture with cross-mirroring so each instance is the insurance copy for the other.

Target architecture:

PVE LXC Gitea          PBS Gitea
─────────────          ─────────
Homelab projects       PBS business code
Lovebug pushes here    (website, n8n, content automation)
Canonical for          Canonical for
  petal-power org        PBS-business org
        ↕ cross-mirror for backup ↕

Locked Decisions

  • Host: PVE LXC (small footprint, native install, no Docker — VM/LXC is the isolation boundary)
  • Database: SQLite on local LXC disk. Adequate for one-human + one-agent push volume; avoids the SQLite-over-NFS corruption footgun.
  • Repo storage: NFS mount from NAS for repos/, lfs/, attachments/. Compute is disposable (rebuildable via Ansible/Terraform), state lives on NAS where it's already in the backup story.
  • Cross-mirror: Gitea's native push-mirror feature in both directions. PVE LXC mirrors homelab repos to PBS; PBS mirrors business repos to PVE LXC.
  • Lovebug access: Only on the new PVE LXC Gitea. PBS Gitea (PBS business code) stays outside Lovebug's reach by default — a natural security boundary.
  • Mirror direction: Canonical lives where active work happens. New LXC is canonical for homelab; PBS stays canonical for PBS business code.
  • Migration mechanism: git push --mirror from herbys-dev for the petal-power org repos (everything was created on herbys-dev anyway). Use Gitea's "Migrate Repository" feature only if any repo has meaningful issue/PR/wiki state worth preserving.

Open Items

  • Confirm petal-power repos don't have meaningful Gitea-native state (issues, PRs, wiki) that git push --mirror would lose. If any do, use Migrate Repository for those specific ones.
  • Decide naming/DNS for new instance (e.g., gitea.herbylab.dev vs subdomain that signals "homelab-Gitea" vs PBS-Gitea)
  • Verify NFS export path on NAS, sizing, and that it's covered by existing NAS backup
  • Identify trigger to execute (see Notes below)

Phases

Phase 1: Provision

  • Create LXC on PVE (size: small, ~2 vCPU / 2GB RAM is plenty for this workload)
  • Configure NFS mount from NAS for repo storage path
  • Install Gitea natively (no Docker)
  • Configure Gitea: SQLite local, repo root + LFS + attachments pointed at NFS mount
  • DNS record for new instance
  • Traefik route + Cloudflare DNS-01 wildcard TLS
  • Test with a throwaway repo to verify the full stack: web UI, SSH push, TLS

Phase 2: Set up org and accounts

  • Create petal-power org on new instance
  • Create Lovebug user account, add SSH key, mirror permissions from PBS instance
  • Pre-populate ~/.ssh/known_hosts on herbys-dev with new Gitea's host key (avoid headless SSH hang)

Phase 3: Migrate repos

  • For each repo under /opt/projects/ on herbys-dev: add new remote, git push --mirror to new Gitea
  • Spot-check several repos: full commit history present, all branches present, tags intact
  • If any repos have Gitea-native state worth preserving, use Migrate Repository for those specifically

Phase 4: Cutover

  • Update Lovebug's SSH config and any shell aliases on herbys-dev to point at new Gitea
  • Update any Gitea API tokens Lovebug uses (new instance = new tokens)
  • Test push from Lovebug against new instance
  • Test push from Travis (travadmin) against new instance

Phase 5: Invert the relationship

  • Configure push-mirror on new Gitea: homelab repos mirror outbound to PBS Gitea
  • PBS Gitea is now read-only-ish for homelab repos (writes propagate from new instance via mirror)
  • Verify a test push lands on PBS via mirror within expected delay
  • (Optional) Configure push-mirror PBS → new instance for PBS business repos, so new instance is insurance copy for those

Notes

The reframe that made this plan possible

The starting point: Gitea-on-PBS was bothering me. The reframe: PBS Gitea isn't "where my code lives" — it's the paid offsite insurance copy I already have. PBS is in a different physical location, backed up whole-drive to Linode, and has been correctly serving an insurance role the whole time. That makes the migration a promotion of the new instance to canonical rather than a rescue of code from PBS.

Cost story

No new spend. PBS hosting is already paid. New LXC sits on existing PVE hardware. NAS storage is already in place. The "paid relationship for business-asset backup" principle is satisfied by the existing PBS arrangement — the architectural fix is about where the canonical lives, not about adding a paid service.

Cross-domain consequence

The plan implicitly couples code backup strategy to the PBS server contract. If PBS is ever cancelled or downgraded, the insurance leg evaporates and a replacement (Backblaze B2, rsync.net, etc.) needs to slot in. Worth remembering this when making future decisions about PBS.

Trigger to execute

Not scheduled. Migration is decided-and-waiting. Any of these fires it:

  • A Traefik or OB1 phase wraps cleanly with no immediate next work queued
  • Lovebug needs gnarly work against a repo where having a fully-controlled Gitea is useful prep
  • Gitea-on-PBS needs hands-on attention anyway (upgrade, backup restore, webhook debug) — redirect that time into the migration
  • A "huh, that was uncomfortable" moment on PBS that makes the coupling acute
  • A Saturday morning where focused infra work sounds genuinely fun

Anti-pattern to avoid: letting this become a background nag. The bad state is "I keep meaning to but never do" — that converts reflection-energy into procrastination-guilt.

Self-hosted git landscape (for future reference)

  • Forgejo — community-governed fork of Gitea, near-painless migration path if Gitea Ltd. ever takes a turn. Most plausible exit ramp.
  • GitLab CE — heavier, full DevOps platform. Overkill for this scale.
  • Cgit + Gitolite — Unix-philosophy stack, no web platform. Wrong cluster for Lovebug-style workflow.
  • Sourcehut — email-driven, niche-but-thoughtful. Wrong workflow fit.
  • Gogs — Gitea's ancestor, basically a museum piece in 2026.

The Gitea-vs-Forgejo decision can be deferred indefinitely; not blocking this migration.