Repo of the Day
RayLabsHQ/gitea-mirror: Gitea Mirror auto-syncs GitHub repos to your self-hosted Gitea/Forgejo, with a sleek Web UI and easy Docker deployment.
Published: Sep 4, 2026
Open repository ↗Gitea Mirror auto-syncs GitHub repos to your self-hosted Gitea/Forgejo, with a sleek Web UI and easy Docker deployment. - RayLabsHQ/gitea-mirror
Summary
Gitea Mirror is a TypeScript application that automatically mirrors GitHub repositories (public, private, and starred) into a self-hosted Gitea or Forgejo instance. It provides a web UI for configuration, scheduled syncing, Git LFS handling, and metadata mirroring (issues, labels, releases, wiki). It is distributed under AGPL-3.0 and runs on Docker, Proxmox LXC, Nix, or manually with Bun.
What it is useful for
- Backing up GitHub work on your own infrastructure so data survives account deletion or bans. The cleanup step defaults to
archiverather than deletion and is skipped if GitHub is unreachable. - Mirroring whole GitHub organizations with strategies like "Preserve Structure", "Single Organization", "Flat User", or "Mixed Mode".
- GitHub Enterprise (GHES and GHEC with data residency) via
GH_API_URL(for examplehttps://api.TENANT.ghe.com) and a token issued by that instance. - Aggregating from additional sources (beta): GitLab and Gitea/Forgejo. GitHub to Gitea is the documented default; Forgejo behaves like Gitea, and using GitHub or GitLab as a destination uses push targets that are code-only.
- Triggering syncs from CI using personal API keys sent in the
x-api-keyheader against endpoints such as/api/sync/repository. - Single sign-on via OIDC (Google, Azure AD, Okta, Authentik) or reverse-proxy header auth (Authentik, Authelia, Traefik Forward Auth).
How engineers can use it
The documented quick start is:
git clone https://github.com/RayLabsHQ/gitea-mirror.git
cd gitea-mirror
docker compose -f docker-compose.alt.yml up -d
# open http://localhost:4321
The first signup becomes admin, and the GitHub token plus Gitea/Forgejo URL are entered through the web UI.
For unattended operation, set SCHEDULE_ENABLED=true with SCHEDULE_INTERVAL=3600 (or a cron expression like "0 2 * * *"), and GITEA_MIRROR_INTERVAL=8h (also accepts 5m, 30m, 1h, 24h, 1d, 7d). AUTO_IMPORT_REPOS=true imports new repos on startup, and CLEANUP_ORPHANED_REPO_ACTION=archive is the recommended default for orphaned mirrors.
For production, use docker-compose.yml, which supports custom CA certificates, multi-arch images from ghcr.io/raylabshq/gitea-mirror (AMD64/ARM64), and ENCRYPTION_SECRET for AES-256-GCM token encryption at rest. Proxmox LXC and NixOS module installations are also documented.
Documented limitations and caveats:
- Pull requests are mirrored as enriched issues, not real PRs, because the Gitea/Forgejo API does not expose PR creation.
- Destinations are pull mirrors and therefore read-only; commit on the source instead.
- The configured interval must be greater than or equal to the destination's
mirror.MIN_INTERVAL, or syncs can fail. - For first-time mirrors of large repositories with LFS or metadata, avoid short intervals; start at
1h–8h. - LFS requires
LFS_START_SERVER = trueand Git v2.1.2+ on the destination server. - Rotating the GitHub token does not always update stored mirror credentials on existing repos; the README recommends editing the repository's Mirror Settings in Gitea/Forgejo, or recreating the mirror.
See the README and docs/ENVIRONMENT_VARIABLES.md for the full configuration reference.