Stay Ready to Leave GitHub
Keep your exit hatch open
GitHub can change pricing, authentication rules, or terms without notice. With Gitea Mirror running, you always have a live copy of code and metadata inside infrastructure you control—so switching to self-hosted Gitea, Forgejo, or something else becomes a DNS change, not a fire drill.
Requirements
- Production-ready Gitea instance (backed by your usual storage and TLS)
- Gitea Mirror configured with owner discovery and metadata sync
- Documentation of your current GitHub org structure (for validation)
- Optional: reverse proxy + SSO for a smooth cutover experience
Step-by-step
1. Mirror everything continuously
- In Configuration → Connections, add every GitHub organization you care about as an owner. Auto-discovery pulls new repositories on the next scheduler run.
- Set the organization strategy to Preserve Structure so Gitea mirrors the GitHub org layout.
- Open Mirror Content to enable metadata, releases, and Git LFS, ensuring issues, pull requests, and binaries survive the switchover.
2. Simulate a cutover
- Pick a pilot team.
- Ask them to work exclusively out of the Gitea mirror for a sprint.
- Capture feedback about permissions, webhooks, CI integrations, and adjust.
3. Keep integrations dual-homed
- Point your CI (e.g. Woodpecker, Jenkins) at both GitHub and Gitea using mirrored tokens.
- Maintain matching webhook payloads so automation keeps running post-swap.
- Mirror secrets (deploy keys, bot accounts) into the Gitea org to remove blockers.
4. Document the flip procedure
- Write a runbook: DNS updates, webhook changes,
git remote set-urlcommands. - Version-control the document inside the mirror so updates stay in sync.
- Rehearse twice a year; include steps to roll back to GitHub if needed.
5. Keep a second copy on a different host
Since 3.31 the destination does not have to be Gitea. Forgejo is a named destination, and GitHub and GitLab are push destinations (all three beta). A second Gitea Mirror account with a GitLab group as its destination gives you a copy on a different company’s infrastructure at no extra cost, and the push engine keeps it identical to the source on every sync. Each account has one source and one destination, so run one account per direction. See Mirror to GitHub or GitLab.
6. Watch for drift
- Review the repositories dashboard weekly for new projects, teams, or permission mismatches.
- Check the Automation tab—if the scheduler is enabled, auto-discovery keeps owners current.
- Use the Activity Log and
/api/eventsexport to alert on failures before your recovery point objective is breached. - Run Reconcile with destination from the Repository Cleanup card now and then. It lists mirrors on Gitea the database does not know about and rows whose mirror is gone, and fixes both on request without deleting anything. See Adopt existing Gitea mirrors.
Success criteria
- A developer can change their
originremote to Gitea and push without errors. - CI pipelines succeed when pointed exclusively at the mirror.
- All active repos have synced within your SLA (for example, last run < 2 hours ago).
- The runbook includes contact info, rollback steps, and verification checklists.
Related playbooks
FAQ
How do I confirm the mirror is still catching new repositories?
Check the Configuration → Connections screen for the Last imported timestamp and ensure the scheduler in Automation is enabled. Auto-discovery runs with each scheduled sync.
What interval should I run before a potential cutover?
Keep Automatic syncing at 15–30 minutes for active organizations. That keeps the lag well under an hour if you have to pivot suddenly.
Can I script the cutover?
Yes. Use the /api/export configuration JSON and the repositories CSV export to generate runbooks, then pair them with infrastructure-as-code (DNS, reverse proxy, CI) so flipping endpoints becomes repeatable.
Related guides
- The full migration guide for when the exit hatch gets used
- Compare backup tools to sanity-check this approach against the alternatives
