---
layout: ../../layouts/UseCaseLayout.astro
title: "Sync GitHub to Your Self-Hosted Gitea"
description: "Keep a homelab Gitea instance continuously updated with GitHub by using Gitea Mirror's discovery, scheduling, and metadata sync."
canonical: "https://gitea-mirror.com/use-cases/sync-github-to-self-hosted-gitea/"
---

# 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 `repo` enabled (add the `read:org` checkbox under `admin:org` to 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

1. Sign in at `http://<mirror-host>:4321`.
2. Open **Configuration → Connections**.
3. Paste the GitHub PAT and choose the owners (user + orgs) you want mirrored.
4. 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 minutes` keeps an active GitHub org nearly live, while `2–4 hours` is fine for quieter repos.
- Leave the scheduler running so auto-discovery and repository cleanup keep working in the background.

<figure class="mt-8 flex flex-col items-center">
  <img
    src="/assets/dashboard.png"
    alt="Gitea Mirror dashboard showing overall sync status for GitHub organizations and repositories."
    class="w-full max-w-5xl rounded-xl border border-muted shadow-sm"
    loading="lazy"
  />
  <figcaption class="mt-3 text-sm text-muted-foreground text-center">
    Monitor GitHub-to-Gitea sync health from the dashboard while the scheduler keeps repositories aligned automatically.
  </figcaption>
</figure>

### 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 gitea` then `git 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/health` to confirm the service stays responsive.
- Export `/api/repos/:id/logs` or the global `/api/events` endpoint 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](../backup-github-repositories/) for the base Docker deployment
- [Run Gitea Mirror inside a Proxmox LXC](../proxmox-lxc-homelab/) 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.
