# Gitea Migration: Command Center → TX1 Dallas

## Migration Overview

**Date:** February 8-9, 2026  
**Duration:** ~2 hours  
**Downtime:** ~5 minutes (DNS propagation)  
**Status:** ✅ Complete - 100% Success

---

## Migration Details

### Source Server
- **Host:** Command Center  
- **IP:** 63.143.34.217  
- **Type:** VPS  
- **Gitea Version:** 1.21.5  

### Destination Server
- **Host:** TX1 Dallas  
- **IP:** 38.68.14.26  
- **Type:** Dedicated Server  
- **Gitea Version:** 1.21.5  

---

## Data Migrated

### Repository
- **Name:** firefrost-operations-manual  
- **Organization:** firefrost-gaming  
- **Size:** 11MB  
- **Files:** 140  
- **Branches:** 2 (master, main)  
- **Commits:** Multiple with full history  

### Database
- **Type:** SQLite3  
- **Size:** ~2MB  
- **File:** gitea.db  

### Total Data Size
- **Compressed Backup:** 9.6MB  
- **Uncompressed:** 13MB  

---

## Migration Process

### Phase 1: Pre-Migration Assessment
1. Audited Gitea installation on Command Center
2. Identified repository structure and size
3. Created file manifest with MD5 checksums (140 files)
4. Documented configuration settings

### Phase 2: Backup Creation
1. Stopped Gitea service on Command Center
2. Created complete backup tarball
   - `/var/lib/gitea` (data directory)
   - `/etc/gitea` (configuration)
   - Pre-migration manifest
3. Verified backup integrity

### Phase 3: Server-to-Server Transfer
1. Generated SSH key on Command Center
2. Added public key to TX1
3. Transferred backup via SCP (9.6MB @ 33.6MB/s)
4. Verified transfer with MD5 checksum

### Phase 4: TX1 Installation
1. Created gitea system user and group
2. Created directory structure
3. Downloaded Gitea 1.21.5 binary
4. Restored backup data
5. Set correct permissions

### Phase 5: Configuration
1. Updated ROOT_URL in app.ini
2. Created systemd service
3. Enabled and started service
4. Verified Gitea functionality on localhost

### Phase 6: HTTPS Setup
1. Installed Nginx as reverse proxy
2. Configured proxy to Gitea (port 3000)
3. Obtained Let's Encrypt SSL certificate
4. Configured automatic HTTP→HTTPS redirect
5. Updated Gitea ROOT_URL to HTTPS

### Phase 7: DNS Update
1. Updated Cloudflare A record
   - Changed git.firefrostgaming.com from 63.143.34.217 to 38.68.14.26
   - Kept DNS-only mode (gray cloud)
2. Verified DNS propagation

### Phase 8: Verification
1. Generated post-migration file manifest
2. Compared checksums (all 140 files matched perfectly)
3. Tested web access via HTTPS
4. Verified repository content on both branches
5. Confirmed login functionality

### Phase 9: Decommission
1. Stopped Gitea on Command Center
2. Disabled auto-start
3. Preserved backup and data for safety

---

## Data Integrity Verification

**Method:** MD5 checksum comparison

**Pre-Migration Manifest:**
- Location: `/root/gitea-migration-manifest.txt`
- Files: 140
- Generated: Feb 8, 22:02 CST

**Post-Migration Manifest:**
- Location: `/root/gitea-post-migration-manifest.txt`
- Files: 140
- Generated: Feb 8, 22:17 CST

**Comparison Result:** ✅ **100% Match**
- All 140 files transferred with identical MD5 checksums
- Zero data corruption
- Complete repository history preserved

---

## Technical Configuration

### Nginx Reverse Proxy
```nginx
server {
    server_name git.firefrostgaming.com;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded_Proto $scheme;
    }
    
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/git.firefrostgaming.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/git.firefrostgaming.com/privkey.pem;
}
```

### SSL Certificate
- **Provider:** Let's Encrypt
- **Issued:** February 8, 2026
- **Expires:** May 10, 2026 (90 days)
- **Auto-Renewal:** Configured via Certbot

### Gitea Configuration Changes
```ini
# Changed in /etc/gitea/app.ini
ROOT_URL = https://git.firefrostgaming.com/
```

### Systemd Service
```ini
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target

[Service]
Type=simple
User=gitea
Group=gitea
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always
Environment=USER=gitea HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea

[Install]
WantedBy=multi-user.target
```

---

## Firewall Configuration

**UFW Rules (already present on TX1):**
- Port 80/tcp: ALLOW (HTTP)
- Port 443/tcp: ALLOW (HTTPS)
- Port 22/tcp: ALLOW (SSH via OpenSSH)

---

## Repository Branch Structure

### master (Source of Truth)
- **Default:** Yes
- **Content:** Full operations manual
- **Files:** 15+ markdown documents, diagrams folder
- **Purpose:** Active development and documentation

### main
- **Default:** No
- **Content:** Initial setup files (GITEA_README.md, docs/USER_GUIDE.md)
- **Purpose:** Historical reference

**Note:** Future cleanup recommended to consolidate branches.

---

## Migration Timeline

| Time | Event |
|------|-------|
| 22:00 CST | Pre-migration assessment started |
| 22:02 CST | File manifest created (140 files) |
| 22:03 CST | Gitea stopped on Command Center |
| 22:03 CST | Backup created (9.6MB) |
| 22:09 CST | Backup transferred to TX1 |
| 22:12 CST | Gitea binary downloaded on TX1 |
| 22:16 CST | Data restored on TX1 |
| 22:16 CST | Service started on TX1 |
| 22:29 CST | Nginx configured |
| 22:30 CST | SSL certificate obtained |
| 22:31 CST | HTTPS configured |
| 22:33 CST | DNS updated |
| 22:37 CST | Service verification complete |
| 22:39 CST | Web access confirmed |
| 22:40 CST | Migration complete |

---

## Post-Migration Status

### Services Running on TX1
- ✅ Gitea 1.21.5 (port 3000)
- ✅ Nginx reverse proxy (ports 80, 443)
- ✅ Certbot auto-renewal timer

### Access
- **URL:** https://git.firefrostgaming.com
- **SSL:** Valid (Let's Encrypt)
- **Status:** Operational

### Services Stopped on Command Center
- ⏸ Gitea (stopped and disabled)
- 💾 Backup preserved at `/root/gitea-backup-20260208-2203.tar.gz`

---

## Lessons Learned

### What Went Well
1. **Small repository size** (13MB) made migration quick and easy
2. **MD5 checksum verification** provided confidence in data integrity
3. **SQLite database** (single file) simplified backup/restore
4. **Server-to-server SSH** enabled fast, secure transfer
5. **DNS propagation** was nearly instant (gray cloud mode)

### Challenges
1. **Initial 502 error** - Resolved by restarting Nginx
2. **Two-branch confusion** - Identified master as source of truth
3. **Firewall already configured** - Saved time but worth documenting

### Recommendations for Future Migrations
1. Always create file manifests for verification
2. Test HTTPS locally before DNS update
3. Keep backups on source server for 30 days
4. Document branch structure before migration
5. Consider branch cleanup as follow-up task

---

## Backup Strategy

### Command Center
- **Location:** `/root/gitea-backup-20260208-2203.tar.gz`
- **Size:** 9.6MB
- **Retention:** 30 days minimum
- **Purpose:** Rollback capability

### TX1
- **Location:** `/root/gitea-backup-20260208-2203.tar.gz`
- **Size:** 9.6MB
- **Purpose:** Pre-installation reference

### Manifest Files
- Command Center: `/root/gitea-migration-manifest.txt`
- TX1: `/root/gitea-post-migration-manifest.txt`

---

## Future Considerations

### Maintenance Tasks
1. **SSL Renewal:** Automatic via Certbot (verify monthly)
2. **Gitea Updates:** Check for updates quarterly
3. **Backup Rotation:** Implement automated backups on TX1
4. **Branch Cleanup:** Consolidate master/main branches

### Monitoring
- **Uptime Kuma:** Add git.firefrostgaming.com to monitoring (Phase 0.5)
- **SSL Expiry:** Monitor certificate expiration
- **Service Status:** Include in Netdata dashboard

---

## Sign-Off

**Migration Completed By:** Michael Krause  
**Assisted By:** Claude (Anthropic)  
**Date:** February 8-9, 2026  
**Status:** ✅ Production Ready  

**Repository:** https://git.firefrostgaming.com/firefrost-gaming/firefrost-operations-manual  
**Branch:** master

---

*End of Migration Log*
