{"id":17645576,"url":"https://github.com/sgaunet/gitlab-backup","last_synced_at":"2026-02-22T23:13:08.700Z","repository":{"id":57619467,"uuid":"356013230","full_name":"sgaunet/gitlab-backup","owner":"sgaunet","description":"CLI tool for backing up GitLab projects and groups. Exports projects via GitLab API to local storage or AWS S3, with support for concurrent exports, rate limiting, and pre/post backup hooks. Features clean architecture, comprehensive testing, and Docker support.","archived":false,"fork":false,"pushed_at":"2026-02-01T19:14:13.000Z","size":693,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-02T03:16:00.248Z","etag":null,"topics":["backup","cli-tool","export","gitlab","golang","project","recursive"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sgaunet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["sgaunet"]}},"created_at":"2021-04-08T18:36:15.000Z","updated_at":"2026-02-01T19:14:11.000Z","dependencies_parsed_at":"2023-09-27T00:45:55.672Z","dependency_job_id":"ebd37ddd-7e33-4564-8bea-d7e71f76f58d","html_url":"https://github.com/sgaunet/gitlab-backup","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/sgaunet/gitlab-backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgaunet%2Fgitlab-backup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgaunet%2Fgitlab-backup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgaunet%2Fgitlab-backup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgaunet%2Fgitlab-backup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sgaunet","download_url":"https://codeload.github.com/sgaunet/gitlab-backup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgaunet%2Fgitlab-backup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29284903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T21:57:15.303Z","status":"ssl_error","status_checked_at":"2026-02-09T21:57:11.537Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup","cli-tool","export","gitlab","golang","project","recursive"],"created_at":"2024-10-23T10:57:33.472Z","updated_at":"2026-02-09T23:07:49.479Z","avatar_url":"https://github.com/sgaunet.png","language":"Go","funding_links":["https://github.com/sponsors/sgaunet"],"categories":[],"sub_categories":[],"readme":"[![GitHub release](https://img.shields.io/github/release/sgaunet/gitlab-backup.svg)](https://github.com/sgaunet/gitlab-backup/releases/latest)\n[![Go Report Card](https://goreportcard.com/badge/github.com/sgaunet/gitlab-backup)](https://goreportcard.com/report/github.com/sgaunet/gitlab-backup)\n![GitHub Downloads](https://img.shields.io/github/downloads/sgaunet/gitlab-backup/total)\n![Test Coverage](https://raw.githubusercontent.com/wiki/sgaunet/gitlab-backup/coverage-badge.svg)\n[![GoDoc](https://godoc.org/github.com/sgaunet/gitlab-backup?status.svg)](https://godoc.org/github.com/sgaunet/gitlab-backup)\n[![Linter](https://github.com/sgaunet/gitlab-backup/workflows/linter/badge.svg)](https://github.com/sgaunet/gitlab-backup/actions/workflows/linter.yml)\n[![Release](https://github.com/sgaunet/gitlab-backup/workflows/release/badge.svg)](https://github.com/sgaunet/gitlab-backup/actions/workflows/release.yml)\n[![Snapshot](https://github.com/sgaunet/gitlab-backup/workflows/snapshot/badge.svg)](https://github.com/sgaunet/gitlab-backup/actions/workflows/snapshot.yml)\n[![License](https://img.shields.io/github/license/sgaunet/gitlab-backup.svg)](LICENSE)\n\n# gitlab-backup\n\nThis tool can be used to export project or every projects of a gitlab group. It uses the API of gitlab to get an archive of exported project.\n\n**Features:**\n* Export GitLab projects or entire groups using GitLab's native export API\n* Two storage options: local folder or S3\n* Pre/post backup hooks support\n* Configurable rate limiting for GitLab API\n* Concurrent project exports for groups\n\n# Usage by configuration file\n\n\nExample: \n\n```yaml\n# debuglevel: \"info\"\ngitlabGroupID: XXXX\ngitlabProjectID: YYYY\nlocalpath: \"/backup\"\ngitlabtoken:\n# gitlaburi: https://gitlab.com\n# tmpdir: /tmp\n# exportTimeoutMins: 10  # Export timeout in minutes (default: 10, increase for large projects)\nhooks:\n    prebackup: \"\"\n    postbackup: \"\"\ns3cfg:\n  endpoint: \"http://localhost:9090\"\n  bucketName: \"ephemeralfiles\"\n  bucketPath: \"test\"\n  region: \"us-east-1\"\n  accesskey: \"\"\n  secretkey: \"\"\n```\n\n## Archive Structure\n\nThe tool creates a standard tar.gz archive using GitLab's native project export API. The archive contains the complete project including repository, wiki, issues, merge requests, labels, and all other project data.\n\nThe final archive is named: `{projectName}-{projectID}.tar.gz`\n\n**parameters of the configuration file can be override by environment variable**\n\nLaunch the program: `gitlab-backup -c configuration.yaml`\n\n# Usage by CLI Flags\n\n`gitlab-backup` now supports rich command-line arguments that can override configuration file and environment variable settings. This makes the tool easier to use for manual invocations and quick backups.\n\n## Configuration Precedence\n\nSettings are applied in this order (highest priority first):\n\n1. **CLI flags** (`--project-id 123`)\n2. **Configuration file** (`gitlabProjectID: 123`)\n3. **Environment variables** (`GITLABPROJECTID=123`)\n\n## Available Flags\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| `--config`, `-c` | Path to YAML configuration file | (optional) |\n| `--group-id` | GitLab group ID to backup | 0 |\n| `--project-id` | GitLab project ID to backup | 0 |\n| `--output` | Output directory for local storage | \"\" |\n| `--timeout` | Export timeout in minutes | 10 |\n| `--tmpdir` | Temporary directory | /tmp |\n| `--gitlab-url` | GitLab API endpoint | https://gitlab.com |\n| `--version`, `-v` | Show version and exit | |\n| `--help`, `-h` | Show help message | |\n| `--cfg` | Print configuration and exit | |\n\n## CLI Examples\n\n### Minimal CLI-only Usage\n\n```bash\nexport GITLAB_TOKEN=glpat-xxxxx\ngitlab-backup --project-id 123 --output /backup\n```\n\n### Backup Entire Group\n\n```bash\nexport GITLAB_TOKEN=glpat-xxxxx\ngitlab-backup --group-id 456 --output /backup/groups\n```\n\n### Override Config File Values\n\n```bash\n# Use config for most settings, but increase timeout\ngitlab-backup --config production.yaml --timeout 30\n```\n\n### Backup to Custom GitLab Instance\n\n```bash\ngitlab-backup \\\n  --project-id 123 \\\n  --output /backup \\\n  --gitlab-url https://gitlab.mycompany.com \\\n  --timeout 60\n```\n\n## Required Settings\n\nThese settings must be provided via one of the configuration methods:\n\n1. **GitLab Token**: Set via `GITLAB_TOKEN` env var (recommended) or `gitlabtoken` in config file\n2. **Project or Group ID**: Set via `--project-id` or `--group-id` (choose one)\n3. **Storage**: Set via `--output` for local storage, or `s3cfg` section in config file\n\n**Note**: S3 storage requires a config file with the `s3cfg` section, as it involves multiple settings (bucket, region, credentials).\n\n# Usage by environment variable\n\n```\n  AWS_ACCESS_KEY_ID string\n  AWS_SECRET_ACCESS_KEY string\n  EXPORT_TIMEOUT_MIN int\n         (default \"10\")\n  GITLABGROUPID int\n         (default \"0\")\n  GITLABPROJECTID int\n         (default \"0\")\n  GITLAB_TOKEN string\n  GITLAB_URI string\n         (default \"https://gitlab.com\")\n  LOCALPATH string\n         (default \"\")\n  POSTBACKUP string\n         (default \"\")\n  PREBACKUP string\n         (default \"\")\n  S3BUCKETNAME string\n         (default \"\")\n  S3BUCKETPATH string\n         (default \"\")\n  S3ENDPOINT string\n         (default \"\")\n  S3REGION string\n         (default \"\")\n  TMPDIR string\n         (default \"/tmp\")\n```\n\n# gitlab-restore\n\nThe `gitlab-restore` tool restores GitLab projects from archives created by `gitlab-backup`. It validates that target projects are empty before proceeding and restores the repository, labels, and issues.\n\n**Features:**\n* Restore GitLab projects from local or S3-stored archives\n* Validate target project is empty before restoring\n* Restore complete project using GitLab's native Import/Export API (includes repository, wiki, issues, merge requests, labels, and all project data)\n* Progress reporting for each restore phase\n* Graceful interruption handling (Ctrl+C)\n* Multi-platform support (Linux, macOS, Windows)\n\n## Restore Usage\n\n### Basic Restore from Local Archive\n\n```bash\ngitlab-restore \\\n  --config config.yml \\\n  --archive /path/to/backup.tar.gz \\\n  --namespace mygroup \\\n  --project restored-project\n```\n\n### Restore from S3 Archive\n\n```bash\ngitlab-restore \\\n  --config config.yml \\\n  --archive s3://bucket/path/to/backup.tar.gz \\\n  --namespace mygroup \\\n  --project restored-project\n```\n\n### Overwrite Existing Project\n\n**⚠️ Use with caution:** Skip emptiness validation\n\n```bash\ngitlab-restore \\\n  --config config.yml \\\n  --archive /path/to/backup.tar.gz \\\n  --namespace mygroup \\\n  --project existing-project \\\n  --overwrite\n```\n\n## Restore Configuration File\n\nThe restore tool uses the same configuration file as `gitlab-backup`:\n\n```yaml\ngitlabtoken: \"your-gitlab-token\"\ngitlaburi: \"https://gitlab.com\"\ntmpdir: \"/tmp\"\nexportTimeoutMins: 10\n\n# For S3 restores\ns3cfg:\n  endpoint: \"https://s3.amazonaws.com\"\n  bucketName: \"backup-bucket\"\n  bucketPath: \"gitlab-backups\"\n  region: \"us-east-1\"\n```\n\n**Configuration can be overridden by environment variables**\n\n### Restore-Specific Environment Variables\n\n```\nRESTORE_SOURCE string\n       Archive path (local or s3://bucket/key)\nRESTORE_TARGET_NS string\n       Target GitLab namespace/group\nRESTORE_TARGET_PATH string\n       Target GitLab project name\nRESTORE_OVERWRITE bool\n       Skip emptiness validation (default \"false\")\n```\n\n## Restore Process Phases\n\nThe restore operation proceeds through these phases:\n\n1. **Validation** - Verify target project is empty (skip with `--overwrite`)\n2. **Download** - Download archive from S3 (if S3 source)\n3. **Extraction** - Extract archive contents to temporary directory\n4. **Import** - Import complete project via GitLab's Import/Export API (includes repository, wiki, issues, merge requests, labels, and all project data)\n5. **Cleanup** - Remove temporary files\n\n## Restore Requirements\n\n* Target GitLab project must exist (create it first via GitLab UI or API)\n* User must have **Maintainer** or **Owner** permissions on target project\n* For S3 restores: AWS credentials with read permissions\n* Archive must be created by `gitlab-backup` (tar.gz format)\n\n## Installation\n\nDownload both `gitlab-backup` and `gitlab-restore` from [github releases](https://github.com/sgaunet/gitlab-backup/releases).\n\n### Brew\n\n```bash\nbrew tap sgaunet/homebrew-tools\nbrew install sgaunet/tools/gitlab-backup\nbrew install sgaunet/tools/gitlab-restore\n```\n\n# Extended project\n\n[Another project can be used to encrypt archives of exported project and send them to s3. It's gitlab-backup2s3](https://github.com/sgaunet/gitlab-backup2s3) which is using two softwares:\n\n* gitlab-backup (this project)\n* [gocrypt](https://github.com/sgaunet/gocrypt)\n\n# Installation\n\n## Release\n\nDownload the latest release from [github](https://github.com/sgaunet/gitlab-backup/releases) and install it.\n\n## Brew\n\n```bash\nbrew tap sgaunet/homebrew-tools\nbrew install sgaunet/tools/gitlab-backup\n```\n\n# Development\n\nThis project is using :\n\n* golang\n* [task for development](https://taskfile.dev/#/)\n* docker\n* [docker buildx](https://github.com/docker/buildx)\n* docker manifest\n* [goreleaser](https://goreleaser.com/)\n\nUse task to compile/create release...\n\n```bash\n$ task\ntask: [default] task -a\ntask: Available tasks for this project:\n* build:            Build the binary\n* default:          List tasks\n* doc:              Start godoc server\n* image:            Build/push the docker image\n* release:          Create a release\n* snapshot:         Create a snapshot release\n* update-crt:       Update the crt file\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgaunet%2Fgitlab-backup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsgaunet%2Fgitlab-backup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgaunet%2Fgitlab-backup/lists"}