gws cluster
Provision (up) or tear down (down) a cluster and all shared infrastructure for a single environment — without deploying any project services.
Use gws cluster up as a pre-flight step before gws up, in CI runners, or in evaluation harnesses to separate infra setup from service deployment.
gws cluster up
Idempotently provision a cluster and install all shared infrastructure in this order:
- Local container registry (when
registry.mode == "local") - k3d / minikube cluster
gws-systemnamespace- Gateway API CRDs + NGINX Gateway Fabric
- Cluster-wide Gateway resource
- CoreDNS rewrite (
*.{domain}→ Gateway) - gws-router deployment
- Domain-only wildcard TLS certificate
If all 10 readiness checks pass (cluster is already healthy), exits in <2 s with "already ready" — no side effects.
Usage
gws cluster up [--env <name>] [--json] [-v]
Options
| Flag | Default | Description |
|---|---|---|
--env <name> | First env in provision.environments, or dev | Environment to provision |
--json | off | Emit a single JSON object to stdout (silences human output) |
-v, --verbose | off | Verbose logging |
Exit codes
| Code | Meaning |
|---|---|
0 | Cluster is up and all infrastructure is healthy |
1 | Provisioning failed (a fatal step failed) |
2 | Invalid usage (e.g. --env for a remote environment) |
Output
Step 1/4: Initializing local registry...
✓ Registry ready at localhost:5001 (1.2s)
Step 2/4: Starting k3d cluster 'gws-cluster'...
✓ k3d cluster ready (12.3s)
Step 3/4: Installing Gateway API + NGINX Gateway Fabric...
✓ Gateway components ready (45.7s)
Step 4/4: Configuring CoreDNS rewrite + deploying gws-router...
✓ Cluster infrastructure ready (8.1s)
Cluster 'gws-cluster' (env: dev) is ready.
kubeconfig: ~/.kube/config
context: k3d-gws-cluster
registry: localhost:5001
domain: local.getwebstack.dev
Run 'gws up' from a project directory to deploy services.
JSON output (--json)
Emits a single JSON object on stdout, suitable for scripting, CI, and the eval framework:
{
"ok": true,
"envName": "dev",
"clusterName": "gws-cluster",
"clusterType": "k3d",
"kubeContext": "k3d-gws-cluster",
"kubeconfigPath": "/home/user/.kube/config",
"registryMode": "local",
"registryUrl": "localhost:5001",
"domain": "local.getwebstack.dev",
"wallTimeMs": 67200,
"alreadyReady": false,
"warnings": []
}
warningsis non-empty when a non-fatal step (gws-router) failed.alreadyReady: truewhen the readiness check short-circuits with all components green.
Remote-environment guard
If --env resolves to a remote-type environment, the command errors immediately before touching anything:
Error: environment 'prod' is type 'remote'.
Remote clusters are not provisioned by gws cluster up.
Use 'gws up --env prod' to deploy your project to the existing remote cluster.
Examples
# Provision the default environment
gws cluster up
# Provision a named environment
gws cluster up --env staging
# CI / eval pre-flight (JSON output for scripting)
gws cluster up --env ci --json
# Check whether infra is already healthy (exits in <2s if it is)
gws cluster up --json | jq .alreadyReady
gws cluster down
Tear down the cluster registered for a single environment. Only removes the cluster and its state entry for the specified --env — all other environments and their state are untouched.
Contrast with
gws down --delete-cluster, which removes all clusters from~/.gws/state.json. Usegws cluster down --env Xwhen you want env-scoped teardown.
Usage
gws cluster down [--env <name>] [--force]
Options
| Flag | Default | Description |
|---|---|---|
--env <name> | Same resolution as up | Environment to tear down |
--force | off | Skip the orphaned-deployment check |
Orphaned-deployment guard
By default, refuses if any project deployments are still registered against this cluster:
Error: 2 project deployments still registered against cluster 'dev'
(myapp/default, myapp/feature-x).
Run 'gws down --env dev' for each deployment first, or pass --force.
Pass --force to bypass this check when state was manually wiped or the cluster is unrecoverable.
Examples
# Tear down the default environment
gws cluster down
# Tear down a named environment
gws cluster down --env ci
# Force-delete even with orphaned deployments in state
gws cluster down --env dev --force
Concurrency and locking
Concurrent gws cluster up --env A and gws up --env A are serialized via a file lock at ~/.gws/locks/cluster-A.lock (stale threshold: 10 minutes). Different environments (--env A and --env B) always run in parallel safely.
If another process holds the lock, the command errors with:
Cluster environment 'dev' is being provisioned or torn down by another gws process.
Wait for it to complete and retry.
If the other process has crashed, delete '~/.gws/locks/cluster-dev.lock.lock' to clear the lock.
Relationship to gws up
gws up calls the same ClusterOrchestrator.up() code path internally. A cluster pre-provisioned with gws cluster up is reused by gws up without re-installing any infrastructure — gws up sees the cluster as already healthy and skips the infra steps.
This is especially useful in CI pipelines and evaluation harnesses:
# Warm the cluster once in globalSetup
gws cluster up --env ci --json
# Each test run deploys its own project without paying the infra cost
gws up --env ci
See Also
- gws up — Deploy services to the cluster
- gws down — Stop a project deployment
- gws status — Show deployment status and service URLs