Getting Started¶
Get varTrack running locally in under 10 minutes.
Prerequisites¶
- Go 1.21+
- Python 3.11+
- A Celery broker — Redis or MongoDB (configured via
celery_broker_datasourcein the bundle) - At least one configured sink
bufCLI — for proto code generation
Option A — E2E demo (fastest)¶
No manual setup needed. Starts everything in Docker:
This starts a local Git server, MongoDB, ZooKeeper, Redis, and all three varTrack services with a pre-configured bundle. Push any config change to the local repo and watch it sync.
With more sinks and the web UI¶
e2e/docker-compose.live.yml adds S3 on MinIO and Kubernetes ConfigMaps and Helm releases on k3s, and seeds every sink through real Gitea pushes and webhooks:
buf generate # the orchestrator image needs the Python gRPC stubs
cd e2e
docker compose -f docker-compose.yml -f docker-compose.live.yml up -d --build \
gitea redis mongo zookeeper minio minio-init vault vault-init \
k3s k3s-kubeconfig orchestrator-api orchestrator-worker gateway watcher live-seed
cd ../ui && npm install && npm run dev
Open the UI at http://localhost:5173. Two Git servers feed the demo, so sign-in covers two platforms: gitea (http://localhost:3000, the demo configs) and gitea-team (http://127.0.0.1:3001, a payments team with a private repository). Sign in with one and connect the other — every password is VarTrack123:
| Sign in to gitea as… | then connect gitea-team as… | you see |
|---|---|---|
demo-admin |
team-admin |
all 7 rules on one page, and can sync them: the 6 demo rules of tenant default and the payments rule of tenant payments, with no tenant to switch to |
demo-viewer |
demo-viewer |
the 6 demo rules, dry runs only (Sync is disabled and says why; a dry run's log shows in the panel); the payments rule stays hidden — not in that team |
The demo's rule settings come in layers (how a rule is built):
| Layer | In the demo |
|---|---|
config.cue |
e2e/live/config.cue: every rule, the datasources' connections, Vault |
a tenant's bundle.json |
tenant default: vartrack-demo/schemas on gitea, extends the production preset · tenant payments: payments/schemas on gitea-team, extends the team preset on gitea |
a repo's vartrack.json |
demo-configs has one on main and a different one on develop; payments-config has .gitea/vartrack.json, extending a preset in the payments team's own schema repo |
| presets | vartrack-demo/presets (e2e/live/presets): each layer adds prune.protection patterns |
Every environment shows its desired state in Git next to the current state in its sink. See Web UI sign-in to turn sign-in off or set it up for your own platforms.

Option B — Build from source¶
1. Clone and generate proto code¶
2. Write config.cue¶
All three services share one CUE bundle that declares your platforms, datasources, and rules.
bundle: {
platforms: [{
github: {
endpoint: "https://github.com"
push_event_name: "push"
pr_event_name: "pull_request"
secret: "my-webhook-secret"
}
}]
datasources: [{
mongo: {
endpoint: "mongodb://localhost:27017"
database: "vartrack"
collection: "variables"
}
}]
rules: [{
platform: "github"
datasource: "mongo"
file_name: "configs/app.yaml" // file to watch in each repo
repositories: ["my-org/*"] // glob — which repos trigger this rule
destination_template: "{env}-config" // collection name resolved at sync time
self_heal: true
branch_map: {
main: "production"
develop: "staging"
}
}]
}
3. Start the gateway-service¶
APP_ENV=dev \
ORCHESTRATOR_ADDR=localhost:50051 \
CONFIG_PATH=config.cue \
go run ./gateway-service/cmd
Listens on :5657 (webhooks) and :9090 (metrics/health).
4. Start the orchestrator-service¶
cd orchestrator-service
pip install -e .
# API + gRPC server
uvicorn main:app --host 0.0.0.0 --port 8000 &
# Celery worker (separate terminal)
celery -A app.worker.celery worker --queues=webhooks,sync -l info
5. Start the watcher-service¶
Every 60 seconds by default, asks the orchestrator whether each self_heal rule's datasource still matches Git.
6. Register a webhook in GitHub¶
Point your repository webhook to http://your-server:5657/webhooks/mongo:
| Setting | Value |
|---|---|
| Payload URL | http://your-server:5657/webhooks/mongo |
| Content type | application/json |
| Secret | Value of secret from config.cue |
| Events | Pushes + Pull requests |
Every push to a matching repository now triggers a sync automatically.
Verify it works¶
Push a change to a tracked repository, then check MongoDB:
You should see one document for the file, with your config values nested under data (the default STRATEGY_DOCUMENT; set update_strategy: "STRATEGY_KEY_VALUE" for one document per key instead).
Install the CLI¶
The vt CLI lets you sync files directly without a Git push:
cd cli
go build -o vt ./cmd
mv vt /usr/local/bin/vt
# Authenticate with your Git token (GitHub or Gitea)
vt login --server http://localhost:5657 --token <your Git token>
# Push a file manually
vt sync --file configs/app.yaml --datasource mongo --env staging --wait
What vt may do is what your Git token may do in the rule's repositories: push access syncs, read access validates and dry-runs — see Authentication & Authorization. In the live demo, make a Gitea token and use it:
TOKEN=$(curl -s -u demo-admin:VarTrack123 -X POST -H "Content-Type: application/json" \
-d '{"name":"vt","scopes":["read:user","read:repository"]}' \
http://localhost:3000/api/v1/users/demo-admin/tokens | python3 -c "import sys,json;print(json.load(sys.stdin)['sha1'])")
vt login --server http://localhost:5657 --token "$TOKEN"
vt sync --file app-settings.yaml --datasource mongo-primary --env staging --wait # the live demo's rule tracks app-settings.yaml
demo-admin administers the demo repositories, so it can sync anywhere; demo-viewer can only read them, so it can validate and dry-run but not sync (the example OPA policy adds: writers never sync production or configs/secrets/*). The same token, pasted into the Git token card on the UI's Playground page, drives the Playground.
Next steps¶
-
Control exactly where data lands using
{env}and{tenant}placeholders -
Map branch names, PR numbers, and tags to environment names
-
Configure MongoDB, Redis, ZooKeeper, S3, and more
-
Understand how the watcher detects and heals config drift
Next steps¶
- Configuration files — where
config.cue,bundle.jsonandvartrack.jsonlive, and how they make a rule - Onboard a config repository — your own repository, end to end
- Production checklist — before syncing production