continuously mirror your github account to forgejo, keeping github as the source of truth
  • Rust 98.7%
  • Dockerfile 1.3%
Find a file
2026-04-28 19:46:50 +02:00
.github/workflows docker: build release image on tag 2026-04-28 19:46:50 +02:00
src provider: remove forgejo credential workaround 2026-04-28 19:36:24 +02:00
.dockerignore docker: docker image support 2026-02-06 02:26:22 +01:00
.gitignore docker: docker image support 2026-02-06 02:26:22 +01:00
Cargo.lock provider: remove forgejo credential workaround 2026-04-28 19:36:24 +02:00
Cargo.toml provider: remove forgejo credential workaround 2026-04-28 19:36:24 +02:00
Dockerfile docker: docker image support 2026-02-06 02:26:22 +01:00
LICENSE.md docs: basic documentation and license 2026-02-06 04:19:44 +01:00
README.md docker: build release image on tag 2026-04-28 19:46:50 +02:00
rustfmt.toml config: init and parse from env 2026-02-04 16:37:28 +01:00

nerhegeb

A service that continuously mirrors your GitHub account to Forgejo, but keeping GitHub as the source of truth. For those who desire to move away from GitHub but can't.

nerhegeb is a service that automatically mirrors repositories from your GitHub account to a Forgejo instance. This is in a one-way fashion, as GitHub is kept as the source of truth. It also synchronizes changes of metadata like visibility after a repository is already mirrored. This can be used to automatically back up all your repositories to your own forge.

Currently nerhegeb supports the following:

  • Automatic mirroring of public and private repositories
  • Control mirroring on a per-repo basis by adding the nerhegeb topic
  • Synchronizing metadata if changed after mirror creation

You can of course configure what repository types are mirrored, and how the topic impacts them. It will also cease touching repositories which are not (or no longer) a mirror on your Forgejo instance.

To see nerhegeb in action, check out my account on my personal git forge which uses nerhegeb to mirror this here GitHub account.

deployment

Deployment is currently only supported via docker. A docker image is available at ghcr.io/virtcode/nerhegeb:latest for both x86_64 and arm64. An example docker compose service could look like the following.

services:
  nerhegeb:
    image: ghcr.io/virtcode/nerhegeb:latest
    restart: unless-stopped

    environment:
      # forgejo authentication
      FORGEJO_URL: https://my-forge-domain.tld
      FORGEJO_TOKEN: my-forgejo-token
      
      # github authentication
      GITHUB_TOKEN: github_pat_my-github-token
      
      # other configuration
      # SEE_BELOW: for more options

For more information about what scopes the tokens mentioned here require, see below. When first setting up nerhegeb, you can also first perform a dry run for testing your configuration and avoid unintended mirroring.

authentication

As nerhegeb automatically creates mirrors, it needs access to both your source GitHub account and your destination Forgejo account. Which account to mirror from/to is automatically determined from the token, so it is important that the following tokens are generated on the correct accounts. It is recommended to choose long expiration dates, as nerhegeb will cease working if one of the tokens expires.

github

To access the GitHub API, nerhegeb uses a personal access token (PAT). Ideally you should generate a fine-grained access token in your account settings to properly minimize required permissions. To work correctly, nerhegeb requires the following:

  • Choose the account you want to mirror as the resource owner
  • Select All repositories under repository access
  • Add the Contents scope as a read-only permission

You can now provide this token in the GITHUB_TOKEN environment variable.

Note that nerhegeb is going to use this token to check for new repositories, but also given to Frogejo to access the repository to mirror it. So the admin of your Forgejo instance may see this token at some point. This is why it is important that it is kept read-only.

forgejo

To mirror to Forgejo, nerhegeb also requires API access to your Forgejo account. Head to User Settings > Applications on your Forgejo instance and generate a token with the following:

  • Select All (public, private, and limited) under repository access
  • Set the repository permission to read and write
  • Set the user permission to read

You can now provide this token in the FORGEJO_TOKEN environment variable. Note that in order to mirror private repositories properly, the version of your Forgejo server needs to be 15.0.0 or higher, due to a bug not saving credentials in older versions.

configuration

You can configure nerhegeb using environment variables. Below are available options together with their default values. Empty variables have no default are required if not stated otherwise.

To test your configuration without changes to your Forgejo account, you can enable the DRY_RUN environment variable. This will read the state from your Forgejo instance at startup once and then evolve and modify that state locally as long as the application runs. For more info what nerhegeb is actually doing, you can also enable debug logs with RUST_LOG=nerhegeb=debug.

# cron string when to check and synchronize repositories
# needs to be a cron string INCLUDING a seconds term
# the timezone used is always UTC
SCHEDULE="0 0 3 * * * *"
# immediately sync once when the container starts
IMMEDIATE=false

# performs a dry run, not doing any modification on forgejo
# will read current state of forgejo once at startup but only modify it locally
DRY_RUN=false

# url to reach the GitHub api at
GITHUB_URL="https://api.github.com/"
# personal access token to access the api
GITHUB_TOKEN=

# url of the Forgejo instance to mirror at
FORGEJO_URL=
# api token to access the api
FORGEJO_TOKEN=

# syncing interval set for new mirrors
SETTING_INTERVAL="8h0m0s"

# enable mirroring of public repositories
MIRROR_PUBLIC=true
# enable mirroring of private repositories
MIRROR_PRIVATE=true
# enable mirroring of forks
MIRROR_FORKS=false
# what to do with repositories with the `nerhegeb` topic, one of
# - `and`    only mirror enabled repositories that have the topic
# - `or`     mirror enabled repositories and also those with the topic
# - `not`    don't mirror any repositories with the topic
# - `ignore` don't care, ignore the topic
MIRROR_TOPIC=or

# whether to synchronize metadata information to mirrors
# metadata is still copied over when the mirror is created
# currently includes description, topics and website
SYNC_METADATA=true
# how to sync the visibility status
# - `total`  ensure the visibility matches the one on github
# - `weaken` only weaken visibility (i.e. sync when repo is made public)
# - `none`   never sync visibility after creating the mirror
SYNC_VISIBILITY=total

# log level sent to the console
RUST_LOG=nerhegeb=info

development

To work on nerhegeb locally, check out this repository. You can build the project using cargo as usual with cargo build. The release docker image is built for your architecture with

docker build . -t nerhegeb

license

This project is licensed under the GPLv3 License. Have a look at the LICENSE.md file for more information.