faaleoleo · July 2026 · Free Available
Introducing Bacula Forgejo
Forgejo and Codeberg Backup Through Bacula
We are releasing Bacula Forgejo — a production-ready Debian and RPM package that backs up Forgejo instances and Codeberg accounts into your existing Bacula deployment. Repositories, wikis, issues, pull requests, databases, container registries, and package registries — all covered through standard Bacula hooks, with no Bacula plugins required.
Forgejo is not a backup
A self-hosted Forgejo instance stores data across at least four independent locations: bare Git repositories on disk, a relational database that holds issues, pull requests, users, labels, and milestones, an OCI container registry, and a package registry. Backing up only the Git repositories leaves you with code but no issue history, no release binaries, no user accounts, and no database. Backing up only the database leaves you with metadata but no actual code.
Hand-rolled scripts that tar everything together are brittle, produce monolithic archives that cannot be restored item by item, and are never tested until disaster strikes.
If you already run Bacula to protect your infrastructure, your Forgejo data should live under the same retention policies, access controls, and disaster recovery guarantees as everything else. Bacula Forgejo makes that possible without introducing new infrastructure.
What it is
Two binaries. No daemons.
forgejo-backup runs as a Bacula ClientRunBeforeJob script and pulls all Forgejo data into a local staging directory before Bacula's File Daemon sweeps that directory into long-term storage. forgejo-restore runs as a ClientRunAfterJob script and pushes recovered data back to a live Forgejo instance.
The Bacula File Daemon treats the staging directory exactly like any other local path. Your existing FileSets, pools, retention policies, schedules, and tape rotation continue to apply unchanged. No Bacula patches. No enterprise-only features. Compatible with both Bacula Community and Bacula Enterprise.
What gets backed up
A plain git mirror preserves commit history. Bacula Forgejo goes further:
-
01
Git repositories and wikis Bare mirror on first run; incremental
git remote update --pruneon every subsequent run. Separate wiki mirror per repository. -
02
Git LFS objects Content-addressable store — only blobs not already in the staging directory are downloaded. Incremental jobs transfer a fraction of the data of a full run.
-
03
Issues, pull requests, and comments Incremental export via
since=timestamps — only changed records re-fetched. Labels, milestones, and branch protections included. -
04
Forgejo Actions workflows and run logs Workflow definitions and run logs, with a configurable cap on log volume per run.
-
05
Release metadata and binary assets Release records and attached binary assets. Size-matched comparison skips unchanged assets on incremental runs.
-
06
Users, organisations, and SSH / GPG keys User profiles, SSH public keys, GPG keys, organisation structure, team membership, and webhook configuration backed up on every run.
-
07
Database dump SQLite, MySQL, and PostgreSQL supported out of the box. PostgreSQL dumps use
pg_dump --format=directorywith configurable parallelism. -
08
Container and package registries (Full jobs only) OCI image layers via the OCI Distribution API or direct filesystem copy. All Forgejo package types — npm, pip, Maven, Debian, RPM, and more.
Incremental-aware, Codeberg-compatible
From the second run onwards, repositories update with git remote update --prune rather than re-cloning. Issue and release metadata uses since= parameters so only changed records are fetched. ETag caching skips unchanged API responses entirely. Daily Differential jobs typically complete in a fraction of the time of a weekly Full job.
The same tool works against hosted Forgejo instances. Enable remote_mode: true in the configuration file and point forgejo_url at codeberg.org — the tool caps API concurrency, disables filesystem-level operations, and uses only the Forgejo-compatible REST API. No SSH access to the server required. Your Codeberg repositories, wikis, issues, and release assets land in Bacula exactly like data from a self-hosted instance.
Two restore modes
forgejo-restore supports two independent approaches depending on the situation.
API mode restores individual objects. Pass --repos myorg/my-repo to recover a single repository without touching anything else. Flags for organisation, user, database, and registry restore run independently — you do not need to restore everything to recover one thing.
Dump mode uses forgejo admin dump for the fastest possible full-instance disaster recovery when speed matters more than granularity.
Getting started
# Debian / Ubuntu
apt install ./bacula-forgejo_0.1.1_amd64.deb
# RHEL / Rocky / Fedora
dnf install ./bacula-forgejo-0.1.1-1.x86_64.rpm
# Configure
cp /usr/share/doc/bacula-forgejo/config.yaml.example \
/etc/forgejo-backup/config.yaml
chmod 0600 /etc/forgejo-backup/config.yaml
$EDITOR /etc/forgejo-backup/config.yaml
Wire it into your Bacula Director with a ClientRunBeforeJob directive:
Client Run Before Job =
"sudo -u forgejo-backup \
env FORGEJO_BACKUP_TOKEN=<token> \
forgejo-backup --config /etc/forgejo-backup/config.yaml --level %l"
The full configuration reference, Bacula Director example, and administrator guide ship with the package under /usr/share/doc/bacula-forgejo, alongside the forgejo-backup(1) and forgejo-restore(1) man pages.
Where to find it
Bacula Forgejo is published under the BSD 2-Clause licence. The current release is v0.1.1. Packages are GPG-signed with SHA-256 checksums for both .deb and .rpm targets.
Product page: the Bacula Forgejo product page on this site has the full feature summary, coverage breakdown, and quick start guide.
This is the same tooling we use internally to protect our own Forgejo instance. It is actively maintained and ships through the same quality pipeline as everything else we publish — GPG-signed releases, SHA-256 checksums, and a signed bill of materials on every tag.
Questions about integrating Bacula Forgejo into your backup infrastructure? We are available via the contact form below.