continuously mirror your github account to forgejo, keeping github as the source of truth
  • Rust 98.9%
  • Dockerfile 1.1%
Find a file
2026-02-06 16:10:09 +01:00
.github/workflows docker: build in github action 2026-02-06 02:33:15 +01:00
src core: detemine mirror relationship based on url 2026-02-06 16:10:09 +01: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 docker: docker image support 2026-02-06 02:26:22 +01:00
Cargo.toml docker: docker image support 2026-02-06 02:26:22 +01: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 core: detemine mirror relationship based on url 2026-02-06 16:10:09 +01: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:main for both x86_64 and arm64. An example docker compose service could look like the following.

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

    environment:
      # forgejo authentication
      FORGEJO_URL: https://my-forge-domain.tld
      FORGEJO_TOKEN: my-forgejo-token
      FORGEJO_COOKIE: i_like_gitea=my-forgejo-cookie # optional, see below
      
      # 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.

Important

If you are planning to use nerhegeb to mirror private repositories you currently need to provide additional authentication. At the moment, Forgejo looses specified credentials after creating a mirror, which prevents mirrors of private repositories from syncing in the future. This is tracked at forgejo#9503 and forgejo#9629.

The issue is that updating mirror credentials is currently not exposed over the API, so nerhegeb has to set them again after mirror creation using the web interface, which requires cookie authentication. This is not ideal as a cookie to your account is very powerful but the only option at the moment.

To retrieve the cookie, open the developer tools in your browser and go to a request going to your Forgejo instance in the network tab. Copy the part starting with i_like_ (without the semicolon) from the Cookie request headers. Then provide it to nerhegeb using the FORGEJO_COOKIE environment variable.

Note that this cookie will expire depending on how the instance is configured, so nerhegeb might cease working properly at some point. But luckily this should be a temporary workaround until it is fixed.

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=
# cookie to access the web interface (optional)
# see above for why/when this is required
FORGEJO_COOKIE=

# 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.