Skip to content

Offline K8s Kind Runbook

Build Local Images

bash
cd go-platform
make docker-build IMAGE_TAG=local

This builds all Go-platform service images, hoctapaz/migrator:local, and the read-only legacy parser runtime image hoctapaz/go-formula-docx:local.

Create Kind Cluster

bash
make kind-create KIND_CLUSTER=hoctapaz-go

Load Images

Before offline use, make sure base infrastructure and observability images are already available in the local Docker image cache:

bash
for image in postgres:16-alpine redis:7-alpine nats:2-alpine minio/minio:RELEASE.2024-05-10T01-41-38Z prom/prometheus:v2.53.0; do
  docker pull "$image"
done
bash
make kind-load-images KIND_CLUSTER=hoctapaz-go IMAGE_TAG=local

kind-load-images loads all hoctapaz/<service>:<IMAGE_TAG> service images, the hoctapaz/go-formula-docx:<IMAGE_TAG> runtime image, the migrator image, and the pinned base images listed in scripts/dev/services.sh.

Deploy

bash
make k8s-deploy IMAGE_TAG=local

k8s-deploy applies namespace/config/secret manifests, brings up the local Postgres Deployment, waits for it to become available, runs schema migration Jobs, then applies Redis, NATS, MinIO, gateway, service, runtime, observability, and ingress manifests. It finally updates the image tag for every deployment listed in SERVICES plus every runtime image listed in RUNTIME_IMAGES. This keeps make docker-build IMAGE_TAG=<tag>, make kind-load-images IMAGE_TAG=<tag>, and make k8s-deploy IMAGE_TAG=<tag> aligned.

The local Postgres manifest mounts postgres-init-scripts into /docker-entrypoint-initdb.d and stores data in the postgres-local-data PVC. On a brand-new PVC, the init scripts create each service database and the IAM/Profile service-owned roles used by the runtime and migration jobs.

Observability

Prometheus runs in the same namespace and scrapes every service /metrics endpoint. Inspect targets with:

bash
kubectl -n hoctapaz-go port-forward svc/prometheus 9090:9090

Then open http://localhost:9090/targets.

Migrate

bash
make k8s-migrate IMAGE_TAG=local

k8s-migrate runs target schema migration Jobs for every service with SQL files under services/{service}/migrations. The jobs use hoctapaz/migrator:<IMAGE_TAG>, wait for all schema Jobs to complete, and apply only target service schemas. Legacy data backfill remains separate.

Check Status

bash
make k8s-status

Validate Manifest Coverage

Before a kind deploy, verify that each locally built service image has a matching offline Deployment/Service manifest:

bash
make test-runtime-foundation

Equivalent individual checks:

bash
docker compose -f deploy/docker-compose.yml config --quiet
scripts/test/service-task-pack-coverage.sh
scripts/test/service-readme-coverage.sh
scripts/test/k8s-service-coverage.sh
scripts/test/k8s-migration-job-coverage.sh
scripts/test/k8s-observability-coverage.sh
scripts/test/go-formula-runtime-coverage.sh
scripts/test/helm-render-coverage.sh

The coverage check verifies:

  • every service in scripts/dev/services.sh has a K8s manifest
  • manifests use hoctapaz/<service>:local
  • manifests use imagePullPolicy: Never
  • manifests include /healthz and /readyz probes
  • every service with SQL migrations has a schema migration Job
  • migration Jobs use imagePullPolicy: Never and the local migrator image
  • migration Jobs wait for completion before dependent services are deployed
  • local Postgres mounts init scripts and persists data with postgres-local-data
  • IAM/Profile static K8s and Helm renders use service-owned database roles
  • Prometheus scrapes every service /metrics target
  • observability manifests use imagePullPolicy: Never and the pinned local image
  • Helm renders every local service image, Prometheus target, and optional schema migration Job
  • Go Formula DOCX is rendered as a runtime dependency with imagePullPolicy: Never
  • docx-import-service points at http://go-formula-docx:8080 in raw K8s and Helm

Destroy

bash
make k8s-destroy
make kind-delete KIND_CLUSTER=hoctapaz-go

The baseline uses imagePullPolicy: Never for local images and does not require a cloud registry.

Go-platform documentation is generated from repository Markdown.