# Gitea Migration: SQLite → PostgreSQL ## Overview Migrating Gitea from: - **Old**: `git.infra.nkode.tech` (SQLite, Dokploy on 191.101.0.153) - **New**: `git.infra.donovankelly.xyz` (PostgreSQL, Dokploy on 191.101.0.153) This is a **destructive migration** — back up everything before proceeding. --- ## Prerequisites - [ ] DNS: Point `git.infra.donovankelly.xyz` → `191.101.0.153` - [ ] Old Gitea export at `/home/clawdbot/clawd/gitea-export/` on the VPS - [ ] Docker and docker-compose available on the Dokploy server - [ ] The new compose service deployed via Dokploy (but NOT yet migrated) --- ## Step-by-Step Migration ### Step 1: DNS Setup Add an A record: ``` git.infra.donovankelly.xyz → 191.101.0.153 ``` Wait for propagation (check with `dig git.infra.donovankelly.xyz`). ### Step 2: Stop the Old Gitea Instance In Dokploy, stop the old Gitea application (`nkode-giteasqlite`). ```bash # Or via CLI on 191.101.0.153: docker stop ``` ### Step 3: Deploy the New Stack (Fresh, No Data Yet) Deploy the compose service from Dokploy. This will start: - PostgreSQL 16 (empty database) - Gitea (fresh install, connected to Postgres) - Act Runner (will fail until token is set — that's OK) Wait for Gitea to be healthy: ```bash docker logs -f gitea # Look for "Starting new Web server" ``` ### Step 4: Stop Gitea (Keep Postgres Running) ```bash docker stop gitea ``` We need Gitea stopped to safely import data. ### Step 5: Migrate the SQLite Database to PostgreSQL **Option A: Using `gitea dump` and restore (Recommended)** The export already has `gitea-dump.zip`. We'll use Gitea's built-in migration: ```bash # Copy the SQLite database into the Gitea container's volume docker cp /home/clawdbot/clawd/gitea-export/gitea.db gitea:/data/gitea/gitea.db # Start gitea temporarily to run the migration docker start gitea # Run the database migration from SQLite to Postgres docker exec -u git gitea gitea doctor convert --type sqlite --database /data/gitea/gitea.db # If `doctor convert` isn't available in your version, use dump/restore: # First, generate a SQL dump from SQLite using the gitea binary: docker exec -u git gitea gitea dump --type postgres --database /data/gitea/gitea.db --file /tmp/gitea-pg-dump.sql # Then import it into Postgres: docker exec -i gitea-postgres psql -U gitea -d gitea < /tmp/gitea-pg-dump.sql ``` **Option B: Using `gitea migrate` on fresh start** If the above doesn't work cleanly, use pgloader to convert SQLite → Postgres directly: ```bash # Install pgloader (on the host or in a container) docker run --rm --network gitea-net \ -v /home/clawdbot/clawd/gitea-export/gitea.db:/data/gitea.db \ dimitri/pgloader:latest \ pgloader /data/gitea.db \ postgresql://gitea:YOUR_POSTGRES_PASSWORD@postgres:5432/gitea ``` **Option C: Manual approach using Gitea's dump file** ```bash # Extract the dump cd /tmp unzip /home/clawdbot/clawd/gitea-export/gitea-dump.zip # The dump contains gitea-db.sql (SQLite format) # Convert using pgloader or sqlite3 + sed for Postgres compatibility ``` **Recommended approach: Option A with `doctor convert`** ### Step 6: Copy Repository Data and LFS The git repositories, LFS objects, avatars, and other data files need to be copied into the new volume: ```bash # Find the new gitea-data volume mount point VOLUME_PATH=$(docker volume inspect gitea-data --format '{{ .Mountpoint }}') # Stop gitea first docker stop gitea # Copy the data directory contents sudo cp -a /home/clawdbot/clawd/gitea-export/data/git/* ${VOLUME_PATH}/git/ sudo cp -a /home/clawdbot/clawd/gitea-export/data/gitea/avatars ${VOLUME_PATH}/gitea/ sudo cp -a /home/clawdbot/clawd/gitea-export/data/gitea/repo-avatars ${VOLUME_PATH}/gitea/ sudo cp -a /home/clawdbot/clawd/gitea-export/data/gitea/attachments ${VOLUME_PATH}/gitea/ sudo cp -a /home/clawdbot/clawd/gitea-export/data/gitea/uploads ${VOLUME_PATH}/gitea/ 2>/dev/null || true sudo cp -a /home/clawdbot/clawd/gitea-export/data/ssh/* ${VOLUME_PATH}/ssh/ 2>/dev/null || true # Fix ownership (Gitea runs as UID 1000 / git user) sudo chown -R 1000:1000 ${VOLUME_PATH}/ # Start gitea again docker start gitea ``` ### Step 7: Verify the Migration ```bash # Check Gitea logs for errors docker logs gitea --tail 100 # Test the web UI curl -s https://git.infra.donovankelly.xyz/api/v1/version # Log in with your existing credentials # Check that repos, users, orgs, webhooks are all present ``` **Checklist:** - [ ] Can log in with existing user accounts - [ ] All repositories are visible and cloneable - [ ] LFS objects are accessible - [ ] Webhooks are configured - [ ] Organizations and teams are intact - [ ] Avatars display correctly - [ ] SSH keys work (`ssh -T git@git.infra.donovankelly.xyz -p 22222`) ### Step 8: Set Up Gitea Actions Runner ```bash # Generate a runner registration token docker exec -u git gitea gitea actions generate-runner-token # Copy the token output, then update .env: # RUNNER_REGISTRATION_TOKEN= # Restart the runner docker restart gitea-act-runner # Verify the runner is connected docker logs gitea-act-runner ``` You can also register the runner via the Gitea web UI: 1. Go to **Site Administration** → **Runners** 2. Click **Create new runner** 3. Copy the token ### Step 9: Configure Dokploy Domain / SSL In Dokploy, configure the compose service's domain: 1. Go to the "Infrastructure" project → compose service 2. Add domain `git.infra.donovankelly.xyz` pointing to the gitea service on port 3000 3. Enable HTTPS (Let's Encrypt) ### Step 10: Update Git Remotes On all machines that had the old remote: ```bash git remote set-url origin https://git.infra.donovankelly.xyz//.git # or for SSH: git remote set-url origin ssh://git@git.infra.donovankelly.xyz:22222//.git ``` ### Step 11: Clean Up - [ ] Remove the old Gitea application from Dokploy - [ ] Remove old Docker volumes - [ ] Update any CI/CD webhooks pointing to the old domain - [ ] Update any OAuth apps using the old domain - [ ] Remove DNS record for `git.infra.nkode.tech` (optional, keep for redirect) --- ## Rollback Plan If migration fails: 1. Stop the new stack: `docker compose down` 2. Restart the old Gitea container in Dokploy 3. The old data is untouched in `/home/clawdbot/clawd/gitea-export/` --- ## Architecture ``` ┌─────────────────────────────────────┐ │ Dokploy (Traefik) │ │ git.infra.donovankelly.xyz:443 │ │ ↓ :3000 │ │ ┌─────────────────────────────┐ │ │ │ Gitea 1.24 │ │ │ │ (Actions enabled) │ │ │ │ SSH :222 → external :22222 │ │ │ └──────────┬──────────────────┘ │ │ │ │ │ ┌──────────▼──────────────────┐ │ │ │ PostgreSQL 16 │ │ │ │ (gitea database) │ │ │ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────┐ │ │ │ Act Runner │ │ │ │ (CI/CD workflows) │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ ``` ## Files | File | Purpose | |------|---------| | `docker-compose.yml` | Service definitions | | `.env` | Secret values (DO NOT commit) | | `.env.example` | Template for secrets | | `MIGRATION.md` | This document |