Live rollout checkpoint
The rollout checkpoint is the repository's deployment contract:
Five unconditional private buckets — assets, documents, exports, logs, and applications — plus optional archive and
telemetry lanes when named. Project growth adds rows and logical key space; it never creates a cloud bucket per Project.
Each portal lives under its {project-code}/portal/ prefix in the applications bucket. The documents bucket stores
Project-scoped content-addressed projects/<code>/documents/<sha> objects, while Surreal asset rows carry the Project
association, visibility, and provenance used for authorization. Marketing bytes remain available through the same-origin
/assets/* application route while the bucket itself stays private and does not grant allUsers.
New clusters are created with --enable-fleet; the subsequent idempotent reconciliation can therefore report Changing existing fleet membership is not supported. Navigator treats only that exact response as already reconciled and
continues; unrelated Fleet errors still stop setup.
Infrastructure is not deployment. A completed setup provisions infrastructure but not a running application. Ship an
immutable release and prove /readyz, /version, certificate readiness, Restate registration, and the browser surface
before posting the #navigator handoff.
For a prefix <name>, set NAVIGATOR_GKE_CLUSTER_NAME=<name>, NAVIGATOR_GKE_CONTEXT=gke_<project>_<region>_<name>,
NAVIGATOR_K8S_NAMESPACE=<name>, NAVIGATOR_VPC_NAME=<name>-vpc, NAVIGATOR_SUBNETWORK_NAME=<name>-subnet,
NAVIGATOR_GATEWAY_IP_NAME=<name>-gateway-ip, NAVIGATOR_ASSETS_BUCKET=<name>-assets,
NAVIGATOR_DOCUMENTS_BUCKET=<name>-documents, NAVIGATOR_EXPORTS_BUCKET=<name>-exports,
NAVIGATOR_LOGS_BUCKET=<name>-logs, NAVIGATOR_APPLICATIONS_BUCKET=<name>-applications,
NAVIGATOR_GCP_SERVICE_ACCOUNT_ID=<name>-web, NAVIGATOR_DRIVE_GCP_SERVICE_ACCOUNT_ID=<name>-drive, and
NAVIGATOR_WEB_SECRET_NAME=<name>-web-secrets. Bucket names are global; add one stable organization prefix if a short
bucket name is already taken.
Also set NAVIGATOR_GCP_PROJECT_ID, NAVIGATOR_GCP_LOCATION, NAVIGATOR_PUBLIC_HOST, NAVIGATOR_WORKFLOWS_HOST,
NAV_BASE_URL=https://$NAVIGATOR_PUBLIC_HOST, NAVIGATOR_WORKFLOWS_URL=https://$NAVIGATOR_WORKFLOWS_HOST/,
NAVIGATOR_WEB_IMAGE, and NAVIGATOR_ASSET_BASE_URL=$NAV_BASE_URL/assets in that deployment's
deployments/<name>/config.toml. Set that row's own NAVIGATOR_SURREAL_* coordinates and credentials in its
secrets.enc.yaml.
Keep the mail rail complete in every deployment's secrets.enc.yaml: SENDGRID_API_KEY, SENDGRID_FROM_EMAIL,
SENDGRID_INBOUND_SECRET, SENDGRID_EVENTS_SECRET, and SENDGRID_EVENTS_PUBLIC_KEY; staging uses non-production
SendGrid credentials and production uses live credentials authenticated for its domain.
Provision each row with the same region-agnostic command — one run per deployments/ directory, its coordinates
exported from that directory's config.toml (populate the directory first; the config is the source of every coordinate
the provisioner reads, so a row is provisioned only once its directory exists). Each run creates five core buckets and
one Autopilot cluster; configured archive and telemetry lanes are additional:
set -a; eval "$(grep ' = "' deployments/neon-law-stg/config.toml | sed 's/ = /=/')"; set +a
navigator ops gcp setup --dry-run
Check every printed project, region, resource prefix, and the two API batches. Provision the registry hub once before the runtime stacks; it runs no workloads:
navigator ops gcp hub setup \
--project-id ghcr --region us-west4 --dry-run
navigator ops gcp hub setup \
--project-id ghcr --region us-west4
Then apply the already-reviewed plans one deployment at a time. Keep staging first, and do not begin production until its command finishes:
set -a; eval "$(grep ' = "' deployments/neon-law-stg/config.toml | sed 's/ = /=/')"; set +a
navigator ops gcp setup
That is the live resource boundary, per deployment: five core buckets, plus any named archive/telemetry lanes, one
VPC/subnet pair, one reserved gateway address, one Autopilot cluster, one KMS key, and two deployment service accounts.
The command also enables the twenty-two required APIs in that runtime project. A completed command is not yet a deployed
website; ops ship, DNS, and the browser checks later in this workshop remain required.
Setup provisions no database and generates no credential, so there is nothing printed to record. The store's own
credentials go into deployments/<name>/secrets.enc.yaml (sops set — the plaintext never touches disk), then
navigator ops secrets apply --deployment <name>; rotation happens at the provider first, per
docs/deployment-secrets.md.
Resolve every reserved address and record the public value as NAVIGATOR_GATEWAY_IP in the matching config.toml — an
IP is a public coordinate, so it is edited and committed like any other:
for name in $(ls deployments); do
set -a; eval "$(grep ' = "' "deployments/${name}/config.toml" | sed 's/ = /=/')"; set +a
echo "${name}:"
gcloud compute addresses describe "$NAVIGATOR_GATEWAY_IP_NAME" \
--global --project "$NAVIGATOR_GCP_PROJECT_ID" --format 'value(address)'
done
Populate the matching local Kubernetes context before shipping a row:
set -a; eval "$(grep ' = "' deployments/neon-law-stg/config.toml | sed 's/ = /=/')"; set +a
gcloud container clusters get-credentials \
"$NAVIGATOR_GKE_CLUSTER_NAME" --region "$NAVIGATOR_GCP_LOCATION" \
--project "$NAVIGATOR_GCP_PROJECT_ID"
The resulting context name must equal that config's NAVIGATOR_GKE_CONTEXT. Repeat once for each deployment you are
operating.
The canonical matrix is the compact reference for every row.