Sync GitHub to Your Self-Hosted Gitea
Keep SaaS and self-hosted in lockstep
You may still collaborate on GitHub every day, yet want a LAN Gitea copy you control. Gitea Mirror bridges the two: it tracks owners, auto-discovers repos, mirrors metadata, and keeps a local instance only minutes behind upstream without hand-written cron jobs.
Requirements
- Gitea Mirror deployed (Docker, Proxmox LXC, or Helm)
- GitHub PAT with
repoenabled (add theread:orgcheckbox underadmin:orgto mirror organizations; leave write/admin unchecked) - Gitea API token for the target account/org
- Stable connectivity between the mirror host and both GitHub + Gitea
Step-by-step
1. Connect accounts in the admin wizard
- Sign in at
http://<mirror-host>:4321. - Open Configuration → Connections.
- Paste the GitHub PAT and choose the owners (user + orgs) you want mirrored.
- Add your self-hosted Gitea URL and token; pick the destination org structure (typically Preserve structure).
2. Import the repository inventory
- In Configuration → Connections, click Import GitHub Data to pull in every repository, organization, and star you’ve selected.
- Enable Mirror starred repositories if you want personal favorites mirrored alongside org projects, and set a dedicated starred organization in Gitea.
- Auto-discovery runs whenever the scheduler is enabled, so new GitHub repositories will appear automatically after you turn on automatic syncing.
3. Configure sync cadence
- Head to Configuration → Automation and enable Automatic syncing.
- Pick an interval that matches your recovery point objective;
15–30 minuteskeeps an active GitHub org nearly live, while2–4 hoursis fine for quieter repos. - Leave the scheduler running so auto-discovery and repository cleanup keep working in the background.

Monitor GitHub-to-Gitea sync health from the dashboard while the scheduler keeps repositories aligned automatically.
4. Mirror metadata and LFS
In Configuration → Connections → Content & Data:
- Enable Mirror metadata so issues, pull requests (as enriched issues), labels, milestones, and wikis stay in sync.
- Enable Mirror LFS if your repos store binaries; confirm your Gitea instance has LFS enabled.
- If you want deleted GitHub repos archived or removed locally, enable Handle orphaned repositories automatically in the Automation tab and choose the action (Archive or Delete) that matches your retention policy.
5. Validate the local mirror
- Select a repository in the dashboard and use the Sync Repository action.
- In Gitea, verify commit history, tags, issues, and releases match GitHub.
- Run a quick diff:
git remote add gitea http://<gitea>/<owner>/<repo>.git && git fetch giteathengit log origin/main..gitea/main— it should be empty.
Monitoring & health checks
- Watch the Activity Log for failed runs and retry jobs; filter by repository when you need to chase a single mirror.
- Point Healthchecks.io, Uptime Kuma, or Prometheus at
http://<mirror-host>:4321/api/healthto confirm the service stays responsive. - Export
/api/repos/:id/logsor the global/api/eventsendpoint periodically to archive sync history alongside the repositories themselves.
Tips for smooth syncing
- Avoid running more than one mirror against the same Gitea target; let Gitea Mirror manage the schedule centrally.
- When restructuring orgs, temporarily disable automatic syncing, move repos in Gitea, then re-enable the scheduler to avoid churn.
- Rate limits cropping up? Move the mirror onto a different IP or configure GitHub fine-grained PATs per org.
Related playbooks
- Backup GitHub Repositories for the base Docker deployment
- Run Gitea Mirror inside a Proxmox LXC if you want the mirror on a dedicated appliance
FAQ
How quickly can the mirror catch up to GitHub?
Intervals of 15–30 minutes keep most orgs near real-time. You can shorten for critical repos, but watch GitHub API rate limits.
Can I mirror multiple GitHub users and organizations?
Yes. Add each owner in Configuration → Connections, then choose a destination strategy (Preserve structure or a specific org) for Gitea.
Is it safe to store tokens in Gitea Mirror?
Tokens saved via the Configuration UI are encrypted at rest. Rotate them regularly and monitor dashboard alerts for expirations.
