Skip to content
Agent Orchestration
Skill

/self-host-studio

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

BOOST
From plugin
studio
41224 skills
Install
$ npx -y skills add decocms/studio --skill self-host-studio --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/self-host-studio

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

self-host-studio.SKILL.md
name: self-host-studio
description: 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.

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:

uname -m                                   # arm64 (Apple Silicon) or x86_64
docker version --format '{{.Server.Version}}' 2>/dev/null || echo "no docker"
kubectl config current-context 2>/dev/null || echo "no kube context"
kubectl get nodes -o custom-columns='ARCH:.status.nodeInfo.architecture' --no-headers 2>/dev/null
kubectl get storageclass 2>/dev/null       # note the (default) one
helm version --short 2>/dev/null || echo "no helm"

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.

1. **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.

2. **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`.

3. **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[].host` with a `/` `Prefix` path, and `tls` (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.

4. **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=…]`

Read more
Ships withstudio

Open-source control plane for your AI agents. Connect tools, hire agents, track every token and dollar

Get the whole plugin

Other skills on studio.