decocms/studio/self-host-studio
Claude Code and agent skill by decocms/studio
- community
Checking that the SKILL.md file is still in the repository.
Install and self-host deco Studio (the open-source control plane) on the user's own infrastructure. Use when the user wants to install, run, self-host, or deploy Studio locally (Docker, Rancher Desktop, kind, minikube) or on Kubernetes (managed or self-managed), or asks to "install Studio", "self-host decocms", configure the Studio Helm chart, or troubleshoot a Studio install. Detects the environment, picks the right tier, configures the charts correctly, validates end-to-end, and fixes the common failure modes.
Install
npx vskill@latest install decocms/studio/self-host-studioSKILL.md
Self-host deco Studio
Guide a user from nothing to a running, reachable Studio on their own infra. Be interactive: detect what they have, pick ONE tier, configure the chart(s) correctly, run it, then verify it actually works (pods Running + UI reachable
- signup) — don't just report "installed".
Studio hard-needs PostgreSQL and an S3-compatible object store; NATS is bundled; the sandbox (code-exec + previews) is an optional layer.
What you produce is a directory, not a running pod. Every install — laptop or EKS — ends with an install directory the user owns and keeps: an umbrella chart with pinned OCI dependencies plus the values you filled in. Installing is then helm upgrade --install on that directory, and it behaves the same on Rancher Desktop and on a managed cluster — see "The artifact" below. Do not clone this repo and do not install from a checkout; the charts are public OCI artifacts and need no credentials.
0. Detect the environment
Detect what the user has:
No managed Kubernetes? Any local cluster works (all core images are multi-arch, Apple Silicon included): Rancher Desktop, Docker Desktop, k3d, kind, minikube, Colima/OrbStack.
Interview — ask, then fill a values file
Drive the install by ASKING, one question at a time; don't assume. Confirm the detected environment, then walk these. Record answers into a values file you'll helm template-validate and show the user before installing.
- Goal / tier — "Trying it out, a POC on a real cluster, or production?"
→ try-out → Compose (no artifact), or the artifact with bundled dev deps. → POC on a real cluster → the artifact, deps you choose below, dev-grade secrets OK. → production → the artifact + external secrets + HPA.
- Each dependency — managed or in-cluster? (ask per item)
- PostgreSQL (required): managed URL (
database.url/DATABASE_URL) OR
their own in-cluster Postgres. The chart bundles none — for a local tier the artifact carries a throwaway one in templates/.
- Object storage (required — else the API crashes self-provisioning MinIO):
managed S3/GCS/R2 (S3_FORCE_PATH_STYLE=false) OR in-cluster MinIO/Ceph (true). Always set S3_ENDPOINT+S3_BUCKET+ keys.
- ClickHouse (monitoring dashboard, optional): none / managed
(CLICKHOUSE_URL) / in-cluster (chart's clickhouse-operator+-cluster subcharts → two-phase CRD; then provision the studio_monitoring_logs view).
- NATS: bundled (default) OR their own (
nats.enabled=false+NATS_URL).
2b. First install against an empty database? Nothing to configure if the image carries the migration advisory lock — replica count does not matter. On an image that predates it, expect the app pods to crash and restart a few times (deadlock detected, duplicate key ... pg_class_relname_nsp_index) while whichever process wins finishes the DBOS migration. Measured 2-4 restarts per pod on a 3-replica local install; it settled, but the same race is what bricked a customer's database, so treat a pre-lock image as needing the pods held back until the migration Job completes. Every replica migrates the DBOS system schema on boot and the SDK's version bump is an UPDATE with no WHERE; two replicas racing there leave two rows in dbos.dbos_migrations and brick the database permanently. The chart's migrateJob closes this under Argo CD but not under plain helm install.
- Reachability / ingress — the public URL →
BASE_URL+BETTER_AUTH_URL
(http://studio.localhost locally; https://studio.<domain> real). The chart's Ingress is optional and OFF by default, so ask what they have:
- have an ingress controller (nginx/Traefik/ALB)? → set
ingress.enabled=true className+hosts[].hostwith a/Prefixpath, andtls(chart
0.13.0+; it backs onto the release's own Service). Render fails if hosts is empty or a host has no paths.
- cloud, no controller? →
service.type=LoadBalancer+ DNS/TLS at the LB. - Istio/Gateway API? → leave
ingress.enabled=false, add Gateway + HTTPRoute.
Locally it's just the LoadBalancer:80 servicelb. Whatever they pick, BASE_URL/BETTER_AUTH_URL must equal the public URL — auth callbacks come from those, not from the request host.
- Secrets — how do they manage secrets? (ask; never inline in git)
- External Secrets Operator? →
externalSecret.enabled=true+secretPath secretStoreName.- No ESO (common) → they create a plain Secret and set
secret.secretName;
the chart injects every key. Give them the command: kubectl -n <ns> create secret generic studio-secrets --from-literal=BETTER_AUTH_SECRET=… --from-literal=ENCRYPTION_KEY=… --from-literal=S3_ACCESS_KEY_ID=… --from-literal=S3_SECRET_ACCESS_KEY=… --from-literal=DATABASE_URL=… [--from-literal=STUDIO_SANDBOX_SENTINEL_TOKEN=…]
- Local/dev → fixed inline values are fine (chart-managed Secret).
BETTER_AUTH_SECRET + ENCRYPTION_KEY MUST be stable across restarts.
- Sandbox (code-exec + previews)? The sandbox is NOT part of the Studio
chart — it's two separate charts installed into agent-sandbox-system: sandbox-operator (cluster-wide CRDs + controller) + sandbox-env (per-env template/RBAC/warm pool). So a full install = Studio chart + these two + they must agree. If yes, you MUST wire all three or claims fail (the usual blockers):
serviceAccount.create: trueon Studio (runs as the SA the sandbox RBAC
grants; default → 403 "cannot create sandboxclaims").
- a shared sentinel token: the SAME value in
sandbox-env.sentinel.token
and Studio's STUDIO_SANDBOX_SENTINEL_TOKEN (generate one: openssl rand -hex 32). Missing → Studio cold-provisions and the template rejects DAEMON_TOKEN.
STUDIO_AGENT_SANDBOX_ENABLED=true,STUDIO_ENV=<env>,
STUDIO_SANDBOX_TEMPLATE_NAME=studio-sandbox-<env>. All three live in ONE artifact, so the values file is the only place the handshake has to be right. Preview URLs need the preview Gateway (prod) or the in-process proxy (local). (In-cluster ClickHouse is likewise separate-ish — the Studio chart's clickhouse-operator/-cluster subcharts, opt-in, two-phase CRD.)
- Write the artifact → validate → confirm → install. Generate the directory
below, helm dependency build, helm template it, show the user the plan, then install and verify (§3). Never install before the template renders clean.
The artifact — a directory the user owns
A full install spans three charts (Studio + sandbox-operator + sandbox-env) that must agree on a service account and a shared token. Threading that by hand across three helm install commands is where installs break. So always produce one umbrella directory instead, whatever the tier:
This is the deliverable. It is portable — the same directory installs on Rancher Desktop and on EKS, because nothing in it points at a local path — and it is reviewable, diffable, and committable to their infra repo. It is also how deco's own internal deploy works.
<name>/Chart.yaml:
Pin real versions, never `"*"` or a range. Resolve the current ones first and write those numbers in:
<name>/values.yaml — nest each subchart's config under its name, wiring the interview answers AND the cross-chart handshake: chart-deco-studio.serviceAccount.create=true, the shared sentinel token on both chart-deco-studio…STUDIO_SANDBOX_SENTINEL_TOKEN and sandbox-env.sentinel.token, and sandbox-operator.allowForeignNamespace=true (the operator self-pins to agent-sandbox-system regardless).
<name>/templates/ — the user's extras: ExternalSecrets, a CNPG Postgres, extra config. For a local tier, also drop in throwaway Postgres + MinIO; the reference copy is self-contained (it reads no values), so fetch it verbatim:
That gives fixed Services studio-db and studio-minio to point database.url and the S3_* values at. Local only — say so in the README you generate, and never suggest it for a real cluster.
<name>/secrets.sh — the kubectl create secret command with the generated values, so a rerun is reproducible. Gitignore it; never inline secret material in values.yaml. With ESO, skip it and set externalSecret.* instead.
For the value shapes (managed vs in-cluster deps, secrets with and without ESO, ingress, sandbox posture, compute sizing) read `selfhost/production` and the Kubernetes guide.
1. Pick a tier
The tiers differ in what values.yaml says, not in how you install. Kubernetes tiers produce the same artifact and the same command; only the dependency choices and the secret handling change.
| Tier | Deps | Best for | |
|---|---|---|---|
| Local — Compose | all bundled, no Kubernetes | trying it out on one host | |
| Local — Kubernetes | throwaway Postgres + MinIO in templates/, bundled NATS | testing on a laptop cluster | |
| Production — Kubernetes | external/managed Postgres + S3, optional managed ClickHouse | staging / prod |
1a. Compose (bundled everything)
The only tier with no artifact — it is a single compose file, not Helm. Runs Studio + Postgres + NATS + MinIO, all wired, no external services:
open http://localhost:3000, sign up (first user = org owner). Override the dev defaults via a .env next to the compose file.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingselfhost/skills/self-host-studio/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/decocms/studio/self-host-studio)