Live rollout checkpoint
The rollout checkpoint is the repository's deployment contract:
Six unconditional private buckets — assets, documents, exports, logs, PostgreSQL backups, 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. The retired Portal's objects remain under a {project-code}/portal/ prefix in the
applications bucket until an operator deletes them by hand. 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 recording the release 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; choose an available name under your
organization's naming convention.
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 row's
$NAVIGATOR_DEPLOYMENTS_DIR/deployments/<row>/config.toml. Set that row's own NAVIGATOR_SURREAL_* coordinates and
credentials in its encrypted secrets.enc.yaml.
Keep the mail rail complete in every deployment's encrypted secrets.enc.yaml: SENDGRID_API_KEY,
SENDGRID_FROM_EMAIL, SENDGRID_INBOUND_SECRET, SENDGRID_INBOUND_PUBLIC_KEY, SENDGRID_EVENTS_SECRET, and
SENDGRID_EVENTS_PUBLIC_KEY. Use credentials appropriate to that row's environment and host.
Provision each row with the same region-agnostic command — one run per private deployment row, with its coordinates
exported from that row's config.toml. Set the variables below from the operator-managed root; the example does not
create, decrypt, or provision private rows. Each run creates six core buckets and one Autopilot cluster; configured
archive and telemetry lanes are additional:
: "${NAVIGATOR_DEPLOYMENTS_DIR:?set this to the operator-managed private deployment root}"
ROW="${ROW:?set this to the selected row name}"
CONFIG="$NAVIGATOR_DEPLOYMENTS_DIR/deployments/$ROW/config.toml"
set -a; eval "$(grep ' = "' "$CONFIG" | 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 "$NAVIGATOR_IMAGE_REGISTRY_PROJECT" --region "$NAVIGATOR_GCP_LOCATION" --dry-run
navigator ops gcp hub setup \
--project-id "$NAVIGATOR_IMAGE_REGISTRY_PROJECT" --region "$NAVIGATOR_GCP_LOCATION"
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 ' = "' "$CONFIG" | sed 's/ = /=/')"; set +a
navigator ops gcp setup
That is the live resource boundary, per deployment: six 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-three 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 $NAVIGATOR_DEPLOYMENTS_DIR/deployments/<row>/secrets.enc.yaml (sops set — the plaintext never
touches disk), then navigator ops secrets apply --deployment "$ROW" --deployments-dir "$NAVIGATOR_DEPLOYMENTS_DIR";
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 private
config.toml. Keep this public infrastructure coordinate in the operator-managed deployment root:
for CONFIG in "$NAVIGATOR_DEPLOYMENTS_DIR"/deployments/*/config.toml; do
set -a; eval "$(grep ' = "' "$CONFIG" | sed 's/ = /=/')"; set +a
echo "${CONFIG%/config.toml}:"
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:
: "${ROW:?set this to the selected row name}"
CONFIG="$NAVIGATOR_DEPLOYMENTS_DIR/deployments/$ROW/config.toml"
set -a; eval "$(grep ' = "' "$CONFIG" | 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.