One star to steer them all.

Overview


🚀 Onboard an application

Dhruva is application-agnostic — each app describes itself with a committed dhruva.yml. Onboarding reads it, registers the app, and drops you into its console.
1
Generate the manifest in your app repo. Run the /dhruva-manifest Claude skill (or node scripts/dhruva-manifest.mjs). It reads the repo — git remote, package.json, infra/ — and writes dhruva.yml. Commit it. Secrets never go in it.
2
Give Dhruva the repo. Pick a method below. From GitLab fetches dhruva.yml with a read token; Paste manifest takes the file contents. No manifest yet? Dhruva derives a stub you finish in Administration.
3
Switch in & operate. You land in the app: set secrets (Utho / GitLab tokens, SSH key), launch the VM, manage DNS, deploy — full OAM&P.
GitLab project path (group/…/name).
Read token (api scope) — fetches dhruva.yml and is saved as this app's gitlab_token for CI/CD + repo clone. Optional for public repos.
Branch to read (default main).
Serving pattern — how the domain is split across backends. Used only when the repo has no dhruva.yml and Dhruva derives one; a committed manifest's own gateway: always wins. patterns ↗
What Dhruva reads from dhruva.yml
dhruva: 1
app:      { slug, name, description }
repo:     { gitlab_project, default_branch }
runtime:  { stack, deploy, health_path }
domains:  { app, root, dns_host }
infra:    { provider, dir, scripts,
            vm: { env, naming, region, plan, image } }
comms:    { provider }
auth:     { provider, mode }          # supabase cloud | self-hosted
gateway:  { pattern, app_paths,       # split ONE FQDN across backends
            static_from }             #   container | split-origin | static
# slug is the stable key. Secrets are NEVER in the manifest —
# set them in Administration → Secrets after onboarding.