Skip to main content

GitLab disaster recovery backup/restore CLI

Project description

gitlab-dr

gitlab-dr is a Python package and CLI for GitLab disaster recovery backup and restore operations.

Requirements

  • Python >=3.6
  • GitLab admin Personal Access Token (PAT)
  • Network access to the source/destination GitLab instances
  • git on PATH (required when repo cloning is enabled, which is the default)

Install

pip install gitlab-dr

CLI execution

gitlab_dr --help
python -m gitlab_dr --help

Authentication and environment variables

All options can be supplied via environment variables instead of CLI flags. Tilde (~) expansion is supported in all path values.

Variable CLI flag Description
GITLAB_DR_URL --gitlab-url GitLab instance URL
GITLAB_DR_TOKEN --token GitLab admin PAT
GITLAB_DR_PASSWORD (prompted) Password for encrypted archives
GITLAB_DR_CLIENT_CERT --client-cert PEM client certificate path (mTLS)
GITLAB_DR_CLIENT_KEY --client-key PEM client key path (mTLS)
GITLAB_DR_CA_CERT --ca-cert Custom CA bundle path

GITLAB_DR_URL and GITLAB_DR_TOKEN are required (either as env vars or CLI flags). GITLAB_DR_PASSWORD is read automatically when --encrypt is set, falling back to an interactive prompt if not set.

Usage

Backup

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --token "$GITLAB_DR_TOKEN"

Scope to a specific group or nested subgroup:

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --group my-group

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --group my-group/sub-group

Include full git repository contents as git bundles (default behaviour — pass --exclude-repo-clone to skip):

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip

Skip repository contents:

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --exclude-repo-clone

Encrypted backup (AES-256):

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --encrypt

When --encrypt is set, the CLI prompts for a password unless GITLAB_DR_PASSWORD is already set.

Directory backup

Use --backup-dir instead of --backup-file to write the backup as plain files in a directory rather than a zip archive. Encryption is not available in this mode.

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-dir /path/to/backup-dir \
  --token "$GITLAB_DR_TOKEN"

This produces:

backup-dir/
  backup.json          ← group/project metadata, variables, merge requests
  backup.log           ← full run transcript
  repos/
    mygroup/
      myproject.bundle ← git bundle (full history preserved)

--repos-as-files (for environment transformation workflows)

Pass --repos-as-files (with --backup-dir) to store each repository as plain checked-out files rather than a git bundle:

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-dir /path/to/backup-dir \
  --repos-as-files

This produces:

backup-dir/
  backup.json
  backup.log
  repos/
    mygroup/
      myproject/       ← plain working tree files, no .git directory
        README.md
        values.yaml
        ...

⚠️ WARNING: Git history is not preserved when using --repos-as-files. On restore, each project will be created with a single initial commit containing the files at the time of backup. All prior commit history from the original repository will be lost. This warning is also printed to the terminal and written to the run log.

This mode is intended for workflows where you need to transform file contents between environments before restoring to a different GitLab instance — for example, using xsyncfar to apply find-and-replace rules across all IaC configuration files when migrating from production to a lab environment. Because every file in the backup directory is plain text, tools like xsyncfar can process both the metadata (backup.json) and the repository files in a single pass.

Typical workflow:

gitlab_dr --backup --backup-dir ./prod-backup --repos-as-files  (from prod GitLab)
    ↓
xsyncfar  (transforms prod strings → lab strings across all files)
    ↓
gitlab_dr --restore --backup-dir ./lab-backup --repos-as-files  (to lab GitLab)

Restore from zip archive

gitlab_dr \
  --restore \
  --gitlab-url https://gitlab.target.example.com \
  --backup-file /path/to/backup.zip \
  --token "$GITLAB_DR_TOKEN"

Restore from directory

gitlab_dr \
  --restore \
  --gitlab-url https://gitlab.lab.example.com \
  --backup-dir /path/to/backup-dir \
  --token "$GITLAB_DR_TOKEN"

When restoring a --repos-as-files backup, each project's files are committed as a single initial commit and pushed:

gitlab_dr \
  --restore \
  --gitlab-url https://gitlab.lab.example.com \
  --backup-dir /path/to/lab-backup \
  --repos-as-files \
  --token "$GITLAB_DR_TOKEN"

mTLS support

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --client-cert /path/to/client.crt.pem \
  --client-key /path/to/client.key.pem

When repo cloning is enabled (the default), the client certificate and key are passed to git via GIT_SSL_CERT and GIT_SSL_KEY environment variables automatically.

To trust a custom CA:

gitlab_dr \
  --backup \
  --gitlab-url https://gitlab.example.com \
  --backup-file /path/to/backup.zip \
  --ca-cert /path/to/ca-bundle.pem

Backup scope

The backup captures recursively discovered groups/subgroups and contained projects, including:

  • Group and project metadata
  • Group and project CI/CD variables (including masked values — store the archive securely)
  • Project merge requests
  • Group member listings
  • Git repository contents (all branches, tags, and refs as git bundles, or as plain files with --repos-as-files) — pass --exclude-repo-clone to skip repos entirely

CI/CD variable access

An admin PAT returns unmasked CI/CD variable values. If a project returns 403 for variables (common on archived projects or projects where the creator account has been removed), the tool automatically retries using Sudo impersonation — first as the project creator_id, then as each current owner/maintainer. If all candidates are exhausted the project is skipped with a warning rather than aborting the run.

⚠️ The backup archive will contain plaintext secrets. Use --encrypt (zip mode) and protect the output appropriately.

Run log

After every backup a .log file is written alongside the archive (e.g. backup.zipbackup.log) containing the full run transcript including all warnings. The terminal summary lists only warnings; the log file contains everything.

Restore behaviour

Restore recreates missing groups/projects and reapplies variables and merge requests where possible. When --include-repos is used on restore, each project's git history is pushed to the target instance via git push --mirror. Failures on individual repositories are reported as warnings and do not abort the rest of the restore.

Empty repositories (no commits) are silently skipped during bundle creation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gitlab_dr-0.3.1.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gitlab_dr-0.3.1-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file gitlab_dr-0.3.1.tar.gz.

File metadata

  • Download URL: gitlab_dr-0.3.1.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gitlab_dr-0.3.1.tar.gz
Algorithm Hash digest
SHA256 318619432b8136511be9fc4543eb47198bab42c98ae7ebcf097905c515315ed5
MD5 0e2a05af4f53e512015b54f29b47a12c
BLAKE2b-256 54020a12f08b79dc74030a660efac4653ee2b5c0f9a1cc351c665d17b7ad97e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for gitlab_dr-0.3.1.tar.gz:

Publisher: publish.yml on tkdpython/gitlab-dr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gitlab_dr-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: gitlab_dr-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 15.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gitlab_dr-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 73d82a279bfbd4e41e6f9f6eb8b54cd35b672cea5d7b5c35681ebf2b71ff5f27
MD5 ae0c678a5d16a23b8b004aa2b6f5929d
BLAKE2b-256 46d3edf369d198d994f245ec0a82b39b360492cd67b4061816236b8052b2e310

See more details on using hashes here.

Provenance

The following attestation bundles were made for gitlab_dr-0.3.1-py3-none-any.whl:

Publisher: publish.yml on tkdpython/gitlab-dr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page