diff --git a/README.md b/README.md index adf9223..f35528f 100644 --- a/README.md +++ b/README.md @@ -375,6 +375,16 @@ PubSub and each BEAM VM's effective port limit: ./scripts/kind-up.sh ``` +Pause the local cluster after Kubernetes verification without deleting its +container, PostGIS volume, Secret, or other cluster state: + +```bash +./scripts/kind-stop.sh +``` + +`./scripts/kind-up.sh` resumes a stopped project-owned control plane before +loading images and reconciling the chart. + Open: - app: diff --git a/docs/operations.md b/docs/operations.md index 8dbfc27..f92a4a2 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -272,6 +272,18 @@ For the project-owned kind cluster, run: ./scripts/kind-rolling-verify.sh local-kind-rollout ``` +The kind control plane is an optional verification environment, not part of +the ordinary public Compose route. Pause it without deleting its container or +Kubernetes state when the cluster is not being tested: + +```bash +./scripts/kind-stop.sh +``` + +The next `./scripts/kind-up.sh` validates the ownership marker and kind labels, +starts the stopped control plane, then continues with image loading and chart +reconciliation. + That script requires both the kind ownership marker and the control-plane cluster label before invoking `rollout restart`. It changes only the web and worker Deployment pod templates. It snapshots application-table counts before diff --git a/docs/verification.md b/docs/verification.md index e087fc4..6c4de16 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -282,6 +282,17 @@ cross-node PubSub. This fixes that specific over-allocation; it is not a production minimum-RAM measurement. Detailed evidence and per-container values are recorded in `docs/performance.md`. +The optional kind and load verification environments were stopped after their +final checks without deleting their containers or volumes. Immediately before +the pause, both isolated databases contained zero users, requests, and +messages; every kind pod was Ready. The stopped kind control plane had been +using 1.706 GiB, while the running load application/database/monitoring +containers used roughly another 1.6 GiB in the same observation. A complete +resume test measured the Kubernetes API Ready after 6.83 seconds, then +`kind-up.sh` reconciled the chart, rolled both 2-replica Deployments, passed +four-node PubSub and the BEAM port-limit checks, and `kind-stop.sh` paused it +again. The ordinary public Compose route remained HTTP 200 throughout. + ## Public staging observation On 2026-07-18, `whoneedhelp.imalto.site` was published through the existing diff --git a/scripts/kind-stop.sh b/scripts/kind-stop.sh new file mode 100755 index 0000000..8c6309a --- /dev/null +++ b/scripts/kind-stop.sh @@ -0,0 +1,35 @@ +#!/bin/sh +set -eu + +ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) +CLUSTER=who-need-help +MARKER="$ROOT/.tools/${CLUSTER}.owned" +CONTROL_PLANE="${CLUSTER}-control-plane" + +if [ ! -f "$MARKER" ]; then + echo "The project ownership marker is absent; refusing to stop a kind cluster." >&2 + exit 1 +fi + +if ! docker inspect "$CONTROL_PLANE" >/dev/null 2>&1; then + echo "The project-owned kind control-plane container does not exist." + exit 0 +fi + +scope=$( + docker inspect "$CONTROL_PLANE" \ + --format '{{index .Config.Labels "io.x-k8s.kind.cluster"}}:{{index .Config.Labels "io.x-k8s.kind.role"}}' +) + +if [ "$scope" != "$CLUSTER:control-plane" ]; then + echo "The kind control-plane container is outside this project's scope." >&2 + exit 1 +fi + +if [ "$(docker inspect "$CONTROL_PLANE" --format '{{.State.Running}}')" != true ]; then + echo "The project-owned kind cluster is already stopped." + exit 0 +fi + +docker stop "$CONTROL_PLANE" >/dev/null +echo "Stopped the project-owned kind cluster; its container and Kubernetes data remain." diff --git a/scripts/kind-up.sh b/scripts/kind-up.sh index af08bfd..496e22f 100755 --- a/scripts/kind-up.sh +++ b/scripts/kind-up.sh @@ -8,6 +8,7 @@ export PATH CLUSTER=who-need-help MARKER="$ROOT/.tools/${CLUSTER}.owned" +CONTROL_PLANE="${CLUSTER}-control-plane" NAMESPACE=who-need-help SECRET_NAME=who-need-help-local POSTGIS_IMAGE=postgis/postgis:18-3.6-alpine @@ -70,6 +71,18 @@ if kind get clusters | grep -Fxq "$CLUSTER"; then echo "Refusing to modify it. Rename/remove it yourself or inspect it first." >&2 exit 1 fi + + if [ "$(docker inspect "$CONTROL_PLANE" \ + --format '{{index .Config.Labels "io.x-k8s.kind.cluster"}}:{{index .Config.Labels "io.x-k8s.kind.role"}}')" \ + != "$CLUSTER:control-plane" ]; then + echo "The existing kind control-plane container is outside this project's scope." >&2 + exit 1 + fi + + if [ "$(docker inspect "$CONTROL_PLANE" --format '{{.State.Running}}')" != true ]; then + docker start "$CONTROL_PLANE" >/dev/null + echo "Resumed the stopped project-owned kind control plane." + fi else kind create cluster --config "$ROOT/deploy/kind/cluster.yaml" touch "$MARKER"