{"id":36964626,"url":"https://github.com/melonamin/ghvault","last_synced_at":"2026-01-13T19:41:00.577Z","repository":{"id":328655301,"uuid":"1115765417","full_name":"melonamin/ghvault","owner":"melonamin","description":"Comprehensive GitHub backup tool with CLI, TUI, and Web interfaces for homelabs and personal setups","archived":false,"fork":false,"pushed_at":"2025-12-14T14:56:15.000Z","size":476,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-16T22:15:39.592Z","etag":null,"topics":["backup","cli","docker","git","github","go","golang","homelab","self-hosted","tui"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/melonamin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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}},"created_at":"2025-12-13T14:05:38.000Z","updated_at":"2025-12-14T16:01:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/melonamin/ghvault","commit_stats":null,"previous_names":["melonamin/ghvault"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/melonamin/ghvault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melonamin%2Fghvault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melonamin%2Fghvault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melonamin%2Fghvault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melonamin%2Fghvault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/melonamin","download_url":"https://codeload.github.com/melonamin/ghvault/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/melonamin%2Fghvault/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28397826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: 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","docker","git","github","go","golang","homelab","self-hosted","tui"],"created_at":"2026-01-13T19:41:00.038Z","updated_at":"2026-01-13T19:41:00.569Z","avatar_url":"https://github.com/melonamin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GHVault\n\n[![Release](https://img.shields.io/github/v/release/melonamin/ghvault?style=flat-square)](https://github.com/melonamin/ghvault/releases)\n[![Go Version](https://img.shields.io/github/go-mod/go-version/melonamin/ghvault?style=flat-square)](https://go.dev/)\n[![License](https://img.shields.io/github/license/melonamin/ghvault?style=flat-square)](LICENSE)\n[![Docker Image](https://img.shields.io/badge/ghcr.io-melonamin%2Fghvault-blue?style=flat-square\u0026logo=docker)](https://ghcr.io/melonamin/ghvault)\n[![Go Reference](https://pkg.go.dev/badge/github.com/melonamin/ghvault.svg)](https://pkg.go.dev/github.com/melonamin/ghvault)\n[![Go Report Card](https://goreportcard.com/badge/github.com/melonamin/ghvault)](https://goreportcard.com/report/github.com/melonamin/ghvault)\n\n\u003cp align=\"center\"\u003e\n \u003cimg width=\"155\" height=\"150\" alt=\"ghv Logo\" src=\"https://github.com/melonamin/ghvault/blob/master/resources/ghv.jpeg\" style=\"border-radius: 16px;\"\u003e\n\u003c/p\u003e\n\n## Overview\n\nGHVault is a comprehensive GitHub backup tool for homelabs and personal setups. It mirrors repositories (including LFS and wikis), exports metadata such as issues and PRs, and gives you CLI, TUI, and Web interfaces so you can keep copies of everything you care about.\n\n### Table of Contents\n- [Why GHVault](#why-ghvault)\n- [Install](#install)\n- [Quick Start](#quick-start)\n- [Interfaces](#interfaces)\n- [Advanced \u0026 Deployment](#advanced--deployment)\n- [License](#license)\n- [Contributing](#contributing)\n\n## Why GHVault\n\n- **Complete coverage** – repositories (bare or mirror), wikis, gists, releases, release assets, labels, milestones, and issue/PR metadata.\n- **Multiple workflows** – unattended CLI jobs, an interactive TUI dashboard, and a browser-based UI.\n- **Homelab friendly** – multi-arch Docker image, persistent storage mounts, and built-in scheduling flags.\n- **Secure auth** – OAuth device flow plus optional encrypted token storage when keychains are unavailable.\n- **Efficient backups** – incremental syncs, Git LFS support, and concurrency tuning.\n- **Flexible filters** – limit by visibility, language, archived status, forks, or glob patterns.\n\n## Install\n\n### Choose your path\n\n| You're… | Start with |\n|---------|------------|\n| Running a homelab or NAS | Docker container for easy persistence |\n| Automating from scripts | Prebuilt binary download |\n| Already in the Go toolchain | `go install github.com/melonamin/ghvault/cmd/ghv@latest` |\n| Hacking on GHVault itself | Clone + `just build` |\n\n### Docker (recommended for homelabs)\n\nPull the latest multi-arch image and run it with persistent volumes:\n\n```bash\ndocker run -d \\\n  --name ghvault \\\n  -p 8080:8080 \\\n  -v ghvault-backups:/home/ghvault/backups \\\n  -v ghvault-config:/home/ghvault/.config/ghvault \\\n  -e GHVAULT_SERVER_PASSWORD=\"change-me\" \\\n  -e GHVAULT_SECRET=\"$(openssl rand -base64 48)\" \\\n  ghcr.io/melonamin/ghvault:latest\n```\n\nThen authenticate via the web UI at http://localhost:8080 or run:\n\n```bash\ndocker exec -it ghvault ghv login --headless\n```\n\nNeed compose files, scheduling, or alternative ports? See [Advanced \u0026 Deployment](#advanced--deployment).\n\n### Download binary\n\nGrab the latest release from [GitHub Releases](https://github.com/melonamin/ghvault/releases):\n\n| Platform | Architecture | Artifact |\n|----------|--------------|----------|\n| macOS | Universal (Intel + Apple Silicon) | `ghv-macos-universal.zip` |\n| Linux | x86_64 | `ghv-linux-amd64.tar.gz` |\n| Linux | ARM64 | `ghv-linux-arm64.tar.gz` |\n\n```bash\n# macOS\ncurl -L https://github.com/melonamin/ghvault/releases/latest/download/ghv-macos-universal.zip -o ghv.zip\nunzip ghv.zip \u0026\u0026 chmod +x ghv \u0026\u0026 sudo mv ghv /usr/local/bin/\n\n# Linux (amd64)\ncurl -L https://github.com/melonamin/ghvault/releases/latest/download/ghv-linux-amd64.tar.gz | tar xz\nchmod +x ghv-linux-amd64 \u0026\u0026 sudo mv ghv-linux-amd64 /usr/local/bin/ghv\n```\n\n### Go install\n\n```bash\ngo install github.com/melonamin/ghvault/cmd/ghv@latest\n```\n\n### Build from source\n\n```bash\ngit clone https://github.com/melonamin/ghvault.git\ncd ghvault\njust build        # Requires the 'just' command runner\n# or\ngo build -o ghv ./cmd/ghv\n```\n\n## Quick Start\n\n### 1. Authenticate\n\nMost setups should run the OAuth **device flow** once and let GHVault store the resulting token (keychain on desktops, encrypted config file on servers). Other options are available when you need non-interactive automation:\n\n| Method | How to trigger | Pros | Considerations |\n|--------|----------------|------|----------------|\n| OAuth device flow *(recommended)* | `ghv login` or `ghv login --headless` | No PAT management, works for CLI/TUI, Docker surfaces codes via logs/API, tokens encrypted locally | Requires a one-time browser visit during setup, needs outbound access to GitHub |\n| GitHub App installation | Configure `auth.github_app` + run `ghv backup` | Ideal for org-managed backups; scoped installation token without user interaction | Requires maintaining the app’s private key and installation ID |\n| Personal access token | Set `GITHUB_TOKEN` or `auth.token` in config (classic or fine-grained PAT) | Works in CI or fully air-gapped environments, no interactive prompts | You must create and rotate the token yourself; scopes must cover repos/orgs/gists you back up |\n\n```bash\n# Interactive login (opens browser)\nghv login\n\n# Headless login (for servers/Docker)\nghv login --headless\n```\n\nTokens are stored securely in your system keychain. When that's unavailable (Docker, headless servers, CI), set `GHVAULT_SECRET` (32+ characters) before running GHVault. The CLI/server refuses to write the fallback `~/.config/ghvault/token.enc` unless this secret is present so the cached OAuth token remains encrypted. Example:\n\n```bash\nexport GHVAULT_SECRET=$(openssl rand -base64 48)\n```\n\n### 2. Run your first backup\n\n```bash\n# Backup everything tied to your account\nghv backup\n\n# Focus on a specific org or repo\nghv backup --org kubernetes\nghv backup --repo owner/repo\n\n# Preview changes without writing data\nghv backup --dry-run\n```\n\n### 3. Pick an interface\n\nUse whatever fits your workflow—CLI for automation, TUI for quick status checks, or Web UI for browser-based control. Details and navigation tips live in the [Interfaces](#interfaces) section below.\n\n## Interfaces\n\n### CLI\n\nPerfect for cron jobs and scripting. A few staples:\n\n```bash\nghv backup [username|org] [flags]   # Run backups\nghv list repos --org example         # Inspect repositories\nghv history log -n 10                # Recent backup runs\nghv status                           # Authentication state\n```\n\nFor the full flag reference, see [CLI Reference](#cli-reference).\n\n### TUI (Terminal UI)\n\n`ghv tui` launches an interactive dashboard showing repositories, backup progress, and logs. Navigation shortcuts:\n- `1` / `d` – Dashboard\n- `2` / `r` – Repositories\n- `3` / `b` – Backup view\n- `4` / `l` – Logs\n- `Tab` – Next view\n- `q` – Quit\n\n### Web UI\n\nStart the web server with:\n\n```bash\nghv serve            # Default 127.0.0.1:8080\nghv serve --addr :3000 --open\n```\n\nAuthenticate directly in the browser via **Sign in from this browser** if you haven’t logged in with the CLI.\n\n- The server binds to `127.0.0.1` by default to keep the UI private on desktop machines.\n- When binding to any other interface (e.g. `--addr :8080` inside Docker), set `server.password` (or `GHVAULT_SERVER_PASSWORD`) or GHVault will refuse to start. The password protects every page/API call.\n- Always set `GHVAULT_SECRET` and `GHVAULT_SERVER_PASSWORD` in your shell (or service unit) before starting the server so the fallback token store remains encrypted:\n\n```bash\nexport GHVAULT_SECRET=$(openssl rand -base64 48)\nexport GHVAULT_SERVER_PASSWORD='change-me'\nghv serve --addr :8080\n```\n\n## Advanced \u0026 Deployment\n\nUse these references when tailoring GHVault to your environment.\n\n### Docker deployment\n\n#### Compose with persistence and optional scheduling\n\n```yaml\nservices:\n  ghvault:\n    image: ghcr.io/melonamin/ghvault:latest\n    container_name: ghvault\n    restart: unless-stopped\n    ports:\n      - \"8080:8080\"\n    volumes:\n      - ghvault-backups:/home/ghvault/backups\n      - ghvault-config:/home/ghvault/.config/ghvault\n    environment:\n      GHVAULT_SERVER_PASSWORD: \"please-change-me\"\n      GHVAULT_SECRET: \"generate-a-long-random-string\"\n      GHVAULT_SCHEDULE_ENABLED: \"true\"\n      GHVAULT_SCHEDULE_CRON: \"0 2 * * *\"  # Daily at 2 AM\n\nvolumes:\n  ghvault-backups:\n  ghvault-config:\n```\n\nImages are published as `latest` and `vX.Y.Z`, supporting both `linux/amd64` and `linux/arm64` architectures.\n\n### Configuration\n\nDefault config path: `~/.config/ghvault/config.yaml`\n\n```yaml\n# Storage\nstorage:\n  output_directory: ./backups\n  structure: nested  # or \"flat\"\n\n# Backup filters\nbackup:\n  filters:\n    include_forks: false\n    include_archived: true\n    visibility: all\n\n  repository:\n    git:\n      enabled: true\n      bare: true\n      lfs: true\n      wiki: true\n\n    metadata:\n      issues: true\n      pull_requests: true\n      releases: true\n      release_assets: true\n      milestones: true\n      labels: true\n\n    attachments:\n      enabled: true\n      max_size_mb: 100\n\n  concurrency:\n    repos: 4\n    api_requests: 2\n\nserver:\n  address: \"127.0.0.1:8080\"\n  password: \"\"\n  trust_proxy: false\n\nschedule:\n  enabled: false\n  cron: \"0 2 * * *\"\n\nlogging:\n  level: info\n  format: text\n```\n\n#### Environment variables\n\n| Variable | Description |\n|----------|-------------|\n| `GHVAULT_CONFIG` | Path to config file |\n| `GITHUB_TOKEN` | GitHub token (alternative auth) |\n| `GHVAULT_SERVER_ADDRESS` | Web server bind address |\n| `GHVAULT_SERVER_PASSWORD` | Protect the Web UI |\n| `GHVAULT_SECRET` | Required when the OS keyring isn't available; encrypts the token file |\n| `GHVAULT_SCHEDULE_ENABLED` | Enable scheduled backups |\n| `GHVAULT_SCHEDULE_CRON` | Cron expression for the scheduler |\n\n### Backup structure\n\n```\nbackups/\n├── owner/\n│   ├── repo.git/                  # Bare git repository\n│   ├── repo.metadata.json         # Issues, PRs, releases, etc.\n│   ├── repo.manifest.json         # Backup manifest\n│   ├── repo.wiki.git/             # Wiki (if enabled)\n│   └── repo.assets/               # Release assets\n│       └── v1.0.0/\n│           └── binary.tar.gz\n└── gists/\n    └── abc123/\n        ├── gist.git/              # Bare gist clone\n        └── gist.metadata.json\n```\n\n### CLI reference\n\n#### `ghv backup`\n\n```\nUsage:\n  ghv backup [username] [flags]\n\nFlags:\n  -o, --output string       Output directory (default \"./backups\")\n      --structure string    Directory structure: flat or nested (default \"nested\")\n  -j, --concurrency int     Number of concurrent backups (default 4)\n  -n, --dry-run             Show what would be backed up\n      --incremental         Only backup repos changed since last backup\n\nRepository Selection:\n      --org string          Backup organization repositories\n  -r, --repo string         Backup a single repo (owner/repo)\n      --gists               Backup gists instead of repos\n      --starred             Backup starred repositories\n\nFilters:\n      --forks               Include forked repos (default false)\n      --archived            Include archived repos (default true)\n      --visibility string   Filter: all, public, private (default \"all\")\n      --language string     Filter by programming language\n\nGit Options:\n      --bare                Clone as bare repositories (default true)\n      --mirror              Clone as mirror (includes all refs)\n\nMetadata:\n      --issues              Export issues (default true)\n      --prs                 Export pull requests (default true)\n      --releases            Export releases (default true)\n      --labels              Export labels (default true)\n      --milestones          Export milestones (default true)\n```\n\n#### Other helpful commands\n\n```bash\nghv list repos              # List your repositories\nghv list repos octocat      # User repositories\nghv list repos --org k8s    # Organization repositories\nghv list orgs               # Your organizations\nghv list gists              # Your gists\nghv history log -n 10       # Last 10 backups\nghv history diff \u003ccommit\u003e   # Show changes between backup snapshots\nghv history restore \u003ccommit\u003e \u003cpath\u003e\n```\n\n### Development\n\nPrerequisites: Go 1.23+, [just](https://github.com/casey/just), [templ](https://templ.guide/), Docker with buildx for multi-arch builds.\n\n```bash\njust build          # Build binary\njust dev            # Run web server in dev mode\njust dev-tui        # Run TUI in dev mode\njust test           # Run tests\njust lint           # Run linter\njust fmt            # Format code\n\njust release        # Build binaries (macOS signed + Linux)\njust release-all    # Build binaries + push Docker image\njust docker-push    # Push multi-arch Docker image to GHCR\n```\n\n## License\n\nMIT License – see [LICENSE](LICENSE) for details.\n\n## Contributing\n\nContributions are welcome! Please open issues or pull requests with improvements, features, or bug fixes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmelonamin%2Fghvault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmelonamin%2Fghvault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmelonamin%2Fghvault/lists"}