groot-share-selfhosted
August 25, 2026 · View on GitHub
groot-share-selfhosted
Repo: github.com/hrodrig/groot-share-selfhosted · Releases: GitHub Releases · App: groot-share (gfs) · Spec: gfs SPECIFICATIONS · Alternatives: groot-share ALTERNATIVES · Changelog: CHANGELOG.md · Roadmap: ROADMAP.md · Disclaimer: DISCLAIMER.md

The problem
Teams on a shared Kubernetes cluster need one catalog of groot diagnostic .tar.gz files — incidents, RCA, handoffs. Archives are often several GB. Producers: laptops, bastion hosts (groot-selfhosted), in-cluster jobs (groot-trigger).
The usual shortcuts fail (full write-up in groot-share):
- Same S3-compatible key on every laptop — revoke or leak hits the whole bucket.
- “Just use Cyberduck” — no per-user audit, retention, or upload API keyed to usernames.
- “Run only groot-trigger” — starts a collect; does not list, download, or retain archives.
gfs is the VPS door when you want login + API keys in front of those archives. This repo is the missing operator packaging: Compose, systemd, Helm — so you do not invent a second deploy dialect.
How this repo solves it
groot-share-selfhosted owns deployment and infra for gfs. Application source, binaries, and ghcr.io/hrodrig/gfs stay in groot-share.
| This repo ships | App behavior lives in |
|---|---|
Compose minimal / Traefik, docker run, systemd, Helm chart gfs | Auth, ingest, Captures UI, audit, retention — gfs SPEC |
GFS_HOST_DATA outside the clone (secrets + SQLite + local files) | Env contract GFS_* — SPEC §5 |
Topologies vps and vps-s3 playbooks | Product freeze — GFS-CONSENSUS |
gfs is not universal. Bucket only, no VPS → S3 only (groot upload.s3 + S3 client) — do not deploy gfs. Decision matrix: groot-share ALTERNATIVES.
Alternatives (at a glance)
Product comparison, pros/cons, and “when not to use gfs” stay in groot-share. This table is the operator map only.
| Situation | Deploy here? | Details |
|---|---|---|
| VPS, archives on disk, small team | yes — topology vps | run/examples/vps · ALTERNATIVES — VPS only |
Bucket + laptops without AWS_* + cluster multi-GB | yes — topology vps-s3 | run/examples/vps-s3 · ALTERNATIVES — VPS + S3 |
| Bucket only, no VPS, operators use S3 tools | no | groot-selfhosted s3-contabo · ALTERNATIVES — S3 only |
| Scheduled / bastion collect | no (groot packaging) | groot-selfhosted → then HTTP to gfs or upload.s3 |
| “Generate capture” button in cluster | no (trigger) | groot-trigger + one storage row above |
→ Full comparison in groot-share docs/ALTERNATIVES.md
Not a replacement for groot. Collect / validate / analyze stay in the groot CLI. groot-trigger starts on-demand collects. groot-selfhosted ships CronJob / bastion playbooks. This repo ships VPS /
vps-s3deploy playbooks for gfs only.
USE AT YOUR OWN RISK. This is not a managed service. You are responsible for your data, secrets, backups, and how you run these stacks. Full text: DISCLAIMER.md.
Related tools (same maintainer):
- pgwd — PostgreSQL connection watchdog (live traffic; deploy: pgwd-selfhosted)
- gghstats — GitHub repo traffic beyond 14 days (live demo; deploy: gghstats-selfhosted)
- kzero — bastion-first declarative workload reset (live traffic; deploy: kzero-selfhosted)
- groot — Kubernetes diagnostics archive (live traffic; deploy: groot-selfhosted)
Table of contents
- The problem
- How this repo solves it
- Alternatives (at a glance)
- Pick a path
- Standalone (native)
- Docker single container
- Docker Compose minimal
- Docker Compose Traefik HTTPS
- Kubernetes Helm
- Repository layout
- Versioning
- Community and policies
- License
Pick a path
Native install preference: release archive / .deb/.rpm (when published) → containers → build from source last.
| You want… | Section |
|---|---|
Linux .deb / .rpm + systemd | run/standalone/linux/README.md |
| install / tarball | Standalone |
Single container (docker run) | Docker single container |
Compose, one service (quick VPS, topology vps) | Docker Compose minimal |
| HTTPS + domain (Traefik + Let’s Encrypt) | Docker Compose Traefik HTTPS |
| Kubernetes | Kubernetes Helm |
Bucket home (vps-s3) | run/examples/vps-s3 |
| S3 only (no gfs) | groot-selfhosted |
Config outside the clone: copy run/common/.env.example → ${GFS_HOST_DATA}/.env, keep SQLite and archives under that directory, prefer run/scripts/compose-stack.sh. git pull must not flatten secrets or DB files.
Default image tag in examples: v0.7.0. Set GFS_VERSION in ${GFS_HOST_DATA}/.env.
Your own VPS: harden the host before exposing gfs. Optional baseline: run/vps-recommended/ (recommendations only). See also DISCLAIMER.md.
Standalone (native)
See run/standalone/README.md — packaged installs first; tarball from groot-share Releases; compile only if nothing else fits.
Docker single container
See run/docker/README.md. Distroless image: UID 65532; bind-mount a host directory to /data.
Docker Compose minimal
export GFS_HOST_DATA=/home/gfs/gfs-data # outside the clone
mkdir -p "$GFS_HOST_DATA"
sudo chown 65532:"$USER" "$GFS_HOST_DATA"
sudo chmod 2775 "$GFS_HOST_DATA"
cp run/common/.env.example "${GFS_HOST_DATA}/.env"
# edit: GFS_HOST_DATA (same path), GFS_BOOTSTRAP_* (min 8 chars), GFS_VERSION
./run/scripts/compose-stack.sh minimal up -d
curl -sS http://127.0.0.1:8080/healthz
Open http://127.0.0.1:8080/login with the bootstrap credentials. After first start, drop GFS_BOOTSTRAP_* from .env and recreate (up -d, not restart alone).
More: run/docker-compose/minimal/README.md
Docker Compose Traefik HTTPS
Prerequisites: DNS A/AAAA for GFS_HOSTNAME → this host; ports 80 and 443 reachable.
export GFS_HOST_DATA=/home/gfs/gfs-data
mkdir -p "$GFS_HOST_DATA"
sudo chown 65532:"$USER" "$GFS_HOST_DATA"
sudo chmod 2775 "$GFS_HOST_DATA"
cp run/common/.env.example "${GFS_HOST_DATA}/.env"
# set GFS_HOSTNAME, ACME_EMAIL, GFS_COOKIE_SECURE=true, GFS_BOOTSTRAP_* (min 8),
# GFS_HOST_DATA, GFS_TOPOLOGY=vps (vps-s3 only with bucket + AWS_*)
./run/scripts/compose-stack.sh traefik up -d
Check: curl -sS -o /dev/null -w '%{http_code}\n' https://your-hostname/healthz
More: run/docker-compose/traefik/README.md
Kubernetes Helm
Chart: run/kubernetes/helm/gfs/ — Deployment, Service, PVC, bootstrap Secret.
kubectl create namespace gfs
kubectl create secret generic gfs-bootstrap -n gfs \
--from-literal=GFS_BOOTSTRAP_ADMIN='your-admin' \
--from-literal=GFS_BOOTSTRAP_PASSWORD='a-long-unique-password' \
--from-literal=GFS_BOOTSTRAP_ADMIN_NAME='Administrator'
helm upgrade --install gfs ./run/kubernetes/helm/gfs \
--namespace gfs \
--set bootstrap.existingSecret=gfs-bootstrap \
--set image.tag=v0.7.0
Helm repo (after first chart publish): index.yaml · packages on Releases as gfs-<chart-version>.tgz.
helm repo add gfs https://hrodrig.github.io/groot-share-selfhosted
helm repo update
helm upgrade --install gfs gfs/gfs -n gfs --create-namespace \
--set bootstrap.existingSecret=gfs-bootstrap \
--set image.tag=v0.7.0
Repo Settings → Pages: source branch gh-pages (created by chart-releaser on first v* tag).
Repository layout
run/
common/.env.example # template → GFS_HOST_DATA/.env
scripts/compose-stack.sh # stacks: minimal | traefik
docker-compose/minimal/
docker-compose/traefik/
docker/
standalone/{linux,macos,windows}/
examples/{vps,vps-s3}/
vps-recommended/ # optional host baseline (Ansible); not gfs install
kubernetes/helm/gfs/ # chart name "gfs" (app); not the repo name
kubernetes/manifests/
# NOT in git: ${GFS_HOST_DATA}/.env, SQLite, archives
Versioning
| Field | Meaning |
|---|---|
Root VERSION | This infra repo (tags v… on main) |
GFS_VERSION / image tag | Upstream gfs on GHCR |
Helm Chart.yaml version: | Chart package |
Helm appVersion | App line (align with groot-share releases) |
Upgrading the app image: set GFS_VERSION in ${GFS_HOST_DATA}/.env, then ./run/scripts/compose-stack.sh minimal pull and … up -d. restart does not swap images.
Community and policies
- DISCLAIMER — use at your own risk; your data, your responsibility
- ROADMAP
- CHANGELOG
- CONTRIBUTING
- SECURITY
- CODE_OF_CONDUCT
- AGENTS
Application issues belong in groot-share — not here.
License
MIT — see also DISCLAIMER.md.