A bundle is a versioned, curated list of platform components and their default versions. You pin against a bundle release (for reproducible CI runs) or against the current edge (for daily iteration). The full schema is documented under Bundle Reference.
TL;DR
1. Prerequisites
Sanity check:
*.dev.
2. Bootstrap your vCluster
1
Resolve project
Forge resolves your default project on the platform side.
2
Ensure host namespace
A per-engineer host namespace
vcluster-<handle> (privileged PSA) is created if missing.3
Install vCluster
helm install of loft/vcluster, idempotent — re-runs are no-ops if the vCluster already exists.4
Wait for vCluster API
The reconciler polls until the inner API is up and pulls its kubeconfig out of a Secret.
5
Resolve bundle
The forge service fetches
bundle.yaml @ 0.4.0 and merges it with your override file (if any) into a concrete component list.6
Deploy components
Each component is
helm install’d into the vCluster, best-effort — a chart-not-found on one component doesn’t abort the rest.grounds cluster up --bundle 0.4.0 after fixing the cause and the reconciler picks up where it left off.
3. Get your vCluster’s kubeconfig
For rawkubectl / helm / devspace access to the inner cluster, the kubeconfig lives in a Secret on the host namespace:
default namespace inside the vCluster is your stack.
A first-class
grounds cluster kubeconfig subcommand is planned but not yet shipped — for now the manual fetch above is the supported path.4. Override a component
Without overrides, every component runs the released image at the version pinned by the bundle. To swap one for your local code, write an override file:overrides/me.yaml
Override schema
See Bundle Reference for the full override schema and field-level documentation.
5. Iterate on a component
The bundle’s per-componentdevspace.workflow field selects which template applies:
- Plugin / lobby / gamemode
- gRPC service
Use DevSpace will:
jar-sync-pod-restart:- Run
./gradlew buildlocally. - Sync the produced JAR into the plugin pod’s
/shared/plugin.jar. kubectl rollout restart deployment/velocity— Velocity’s init-containers re-fetch your JAR.- Watch
build/libs/and re-do all of the above on every change.
6. Inspect the event bus
The bundle has an opt-innats-recorder component that subscribes to chosen subjects and emits each message as JSONL on stdout — useful for debugging cross-service events without writing one-off subscribers.
grounds cluster up, tail it:
bundle.yaml (default: config.>, player.>, friends.>, match.>).
7. Tear down
down is cheap to reverse; delete requires re-running the bundle deploys from scratch. To swap one component out without losing state, use overrides — don’t delete.
8. Troubleshooting
forge says "chart not found" for a component
forge says "chart not found" for a component
The Helm chart for that component type isn’t published yet. The forge response’s
failed[] block tells you exactly which component and which chart URL failed. Either wait for the chart to be released or override the failing component with enabled: false so the rest of the stack still comes up.Pod stuck in Init waiting for fetch-<plugin>
Pod stuck in Init waiting for fetch-<plugin>
The
grounds-velocity chart’s init-containers curl each plugin’s Service at http://<plugin>:8080/plugin.jar. If a plugin pod isn’t ready (e.g. its image doesn’t exist or it’s still pulling), the velocity pod waits. kubectl get pods and look for the plugin pods that aren’t Running.DevSpace sync writes the JAR but Velocity doesn't pick it up
DevSpace sync writes the JAR but Velocity doesn't pick it up
The
jar-sync-pod-restart workflow assumes you set RESTART_TARGET=velocity for plugin-* components. Without the rollout-restart, Velocity keeps the old JAR loaded. Check the onUpload.execRemote block in your devspace.yaml.Tailscale can't resolve nats.dev / postgres.dev
Tailscale can't resolve nats.dev / postgres.dev
You’re not on the internal Grounds tailnet. This is a private network for authorized engineers — if you haven’t been invited yet, ask a maintainer. Once you’re on, run
tailscale status to confirm the routes; if they’re missing, re-run tailscale up accepting the dev-routes ACL.409 'cannot apply bundle to platform workspace'
409 'cannot apply bundle to platform workspace'
You already have a
profile=platform workspace from the older flow. The bundle workflow uses profile=platform-bundle and they’re not interchangeable. grounds cluster delete first, then re-up with --bundle.A component's helm-install errors after a successful first deploy
A component's helm-install errors after a successful first deploy
grounds cluster up --bundle X is idempotent and uses helm install/upgrade. If a chart’s values shape changed between bundle versions, a stale release can block the upgrade. Drop the specific component’s release inside the vCluster (helm uninstall <component> against the vCluster kubeconfig) and re-run cluster up.9. Reference
- Bundle Reference — every field of
bundle.yamland the override-file schema grounds-cli— CLI source + releasesgroundsgg/charts— public Helm charts referenced by bundlesgroundsgg/library-grpc-contracts— shared protobuf event schemas
