Prepare the selected cloud first, then use the shared preview, apply, verification and recovery workflow.
Choose the GCP architecture or AWS architecture. These shared commands assume the corresponding cloud prerequisites have been prepared.
Follow the GCP prerequisites or
AWS prerequisites before cloud-writing commands.
Stage names do not select a cloud; the ignored declaration's home field does.
Use the separate GCP bootstrap procedure or
AWS bootstrap and compatibility check.
npm run bootstrap prepares prerequisites; it does not prove application readiness.
Required application values include OIDC_CLIENT_ID; set and verify them using configuration.
For a stage with verified mdeploy prerequisites, the entrypoint is mdeploy-all.yml.
It defaults to a preview. Example: preview an open PR's merge result in dev:
gh workflow run mdeploy-all.yml --ref main -f stage=dev -f ref='#123' -f components=api+runner -f apply=falseReplace #123 with the intended PR, or use a full commit SHA. Review the resolved SHA, stage identity,
artifact identities and complete resource diff. Then dispatch that reviewed SHA with apply=true.
A fresh PR ref can resolve to a different merge commit; pin the reviewed SHA when applying.
| Ref | Allowed stages | Artifact path |
|---|---|---|
Full SHA or open PR #number |
dev |
Ensure commit images and runner build exist |
Published vX.Y.Z release |
dev, prod |
Version-qualified images and published runner release |
Release dispatches run from main. Production accepts releases only. For a protected production apply:
gh workflow run mdeploy-all.yml --ref main -f stage=prod -f ref=vX.Y.Z -f components=api+runner -f apply=true -f confirm=trueRun a preview of that release first. components=api or runner narrows artifact preparation,
not the entire infrastructure graph. Runs queue per stage; do not cancel a healthy apply to start another.
Image releases are published/promoted through mbuild-release.
Automation callers may supply the optional string inputs requested_by (a public GitHub username) and
request_id (an opaque operation ID). When both are present, the run title appends
· @<public-login> · <opaque-operation-id>. Omitting either preserves the native run title.
These fields provide display and correlation metadata; they do not grant reviewer authority.
Keep email addresses and credentials out of both inputs. Existing apply, confirm and Environment approval requirements still apply.
The AWS deployment guide owns the retained SST path and its compatibility boundary. Its runner update launcher is separate from current mdeploy orchestration.
Local deployment uses the same stage configuration and artifact identities. Publish or promote
images first with mbuild, and prepare the selected runner artifact.
The following example assumes release images vX.Y.Z-<sha> and runner release X.Y.Z already exist:
export BOXLITE_IMAGE_TAG='vX.Y.Z-<full-commit-sha>'
export VERSION='X.Y.Z'
npm run mstage login -- --stage dev
npm run mstage env digest -- --stage dev
npm run mbuild verify -- --tag <full-commit-sha> --version vX.Y.Z --stage dev
npm run mdeploy -- --stage dev --diff
npm run mdeploy -- --stage devSubstitute real values and inspect the preview before the last command. Add --confirm for a
protected stage. For a commit runner build, use the selectors in the runner runbook.
mdeploy --local-env bypasses store loading and is an explicit diagnostic option, not the default.
Configuration owns the file/store/CI boundaries, and
security explains runtime identity and protection. Inspect names with
npm run mstage env list -- --stage dev; value exports belong in a secure destination.
Provide an account-owned token with Zone:Read and DNS:Edit, restricted to the zone used by
STACK_DOMAIN and PROXY_DOMAIN, plus the user domain's zone when the stage sets one (below). Set CLOUDFLARE_DEFAULT_ACCOUNT_ID and CLOUDFLARE_ZONE_ID
to the intended account/zone. Both are required by the current deployment group, alongside the token.
Users' named apps (demo.<STACK_USER_DOMAIN>) live under a registrable domain of their own, so a
named app is never same-site with the dashboard and a blocklisted one does not take the platform's
domain with it. Generated box URLs still sit under PROXY_DOMAIN; moving them is separate work. A stage that sets STACK_USER_DOMAIN also sets CLOUDFLARE_USER_ZONE_ID, the zone
holding that domain. On GCP the edge writes
*.<STACK_USER_DOMAIN> into that zone and issues its certificate through its own DNS authorization;
the apex is not used. The API and the proxy learn the domain as PROXY_APP_DOMAIN. Unset, the stage
offers no named apps. The deploy refuses a user domain under the same registrable domain as
STACK_DOMAIN or an overridden DASHBOARD_DOMAIN (a sibling such as apps.boxlite.ai beside dev.boxlite.ai included), and refuses one
on AWS, whose edge serves none.
The token is created in Cloudflare's dashboard; a provider login does not generate it.
Follow the selected cloud’s deployment guide for credential storage and rotation destinations.
| Check | Evidence to inspect |
|---|---|
| Intended deployment | Resolved stage, cloud/project/account, commit and artifact identities |
| Infrastructure | Successful apply with no unexpected replacement or deletion |
| API and dashboard | Public HTTPS, /api/health, dashboard load and OIDC login |
| Proxy | Healthy load-balancer backends and an actual box preview/tunnel |
| Runners | Fleet registration, target health identity, box create/exec/stop |
| Persistent volumes | Create/mount/write/read using a test volume if enabled |
| Telemetry | A new test event reaches the configured destination and is queryable |
Use the runner, network, and ClickHouse guides to locate the failing boundary. The legacy wrapper's automatic checks do not imply that mdeploy performs the same checks.
| Symptom | Next check |
|---|---|
| Stage/config not found | Ignored declaration and CI environment variable; configuration |
| Missing required key or digest mismatch | Correct the stage store, review values, then certify the intended group |
| Missing image or runner artifact | Verify the exact commit/release in the correct stage; do not treat permission failure as absence |
| Credential failure | Check identity using the selected cloud’s deployment guide |
| Service cannot reach a runner | Private routes, firewall source ranges and DNS |
| Apply succeeded but runner is old | Cloud rollout reports and live health |
| Locked or interrupted deployment | Confirm no writer is running, then follow state recovery |
| Login, invitation or email failure | Identity and mail |
Do not clear a live deployment's lock or restart a healthy service merely because an apply is slow. An apply can partially succeed before failing; inspect cloud and state before retrying or rolling back.
Refresh reconciles the checkpoint; it does not apply a new desired resource graph:
npm run mdeploy -- --stage dev --refresh
npm run mdeploy -- --stage dev --diffFor intentional removal of an unprotected disposable stage, the command is
npm run mdeploy -- --stage <stage> --remove --confirm. Protected stages are refused.
Independent resource protection and retained data can also prevent or outlive removal; inventory them
before calling teardown complete. Bootstrap identities, registries and artifact/state buckets have
separate ownership and are not implicitly erased by removing application resources.
Use runner operations to add capacity. Resource sizes, database availability,
backups and ClickHouse mode come from the stage's deploy block.
Use the separate GCP cost catalog or AWS inventory.
Estimate from the selected region, configuration and traffic rather than a fixed monthly total.
Architecture · mdeploy · mstage · mbuild · ClickHouse · Status page