From d38c70094972acc2528c23e29c53b89791f53e8c Mon Sep 17 00:00:00 2001 From: Ivan Godwin Date: Fri, 17 Jul 2026 20:08:17 -0700 Subject: [PATCH] docs(notifier): describe generic GitOps deployment; guard private plan doc Replace the k8s/-centric deployment section with a provider-agnostic GitOps pattern (Kustomize base+overlay, pinned tags, operator-managed secrets, Gateway API routing) and demote k8s/ to reference examples. Gitignore docs/WEBUI_PLAN.md: this repo is public and that doc holds private infrastructure details (now relocated to the private gitops repo). Co-Authored-By: Claude Fable 5 --- .gitignore | 3 +++ README.md | 63 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 4a8df6a..7032709 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,6 @@ mem.out # Local development overrides docker-compose.override.yml + +# Private planning docs referencing personal infrastructure — never commit +docs/WEBUI_PLAN.md diff --git a/README.md b/README.md index 8b5ef69..46bd6a0 100644 --- a/README.md +++ b/README.md @@ -479,31 +479,58 @@ docker-compose up -d Includes optional services: Kafka, Prometheus, Grafana (commented out by default) -### Kubernetes +### Kubernetes (GitOps) -**Deploy:** +The recommended way to run notifier in Kubernetes is from a GitOps repository +(ArgoCD, Flux, or similar) that reconciles a Kustomize base + per-cluster +overlay, rather than applying manifests by hand. A typical setup: + +- **Kustomize layout:** a `base/` with the Deployment, Service, ConfigMap, and + routing resources, plus an overlay per cluster/environment that sets the + namespace and pins the image tag. Pin an explicit version tag in the overlay — + don't deploy `latest`. +- **Secrets:** keep credentials out of git entirely. Use a secrets operator + (e.g. Vault Secrets Operator, External Secrets) to materialize a Secret, and + inject it via `envFrom` — notifier layers `NOTIFIER_*` environment variables + over the mounted `config.yaml`, so secret fields can be left blank in the + committed ConfigMap. +- **Config:** mount `config.yaml` from a ConfigMap at `/app/config.yaml` with the + non-secret settings (server mode, queue, notifier accounts). +- **Topology:** run a **single replica** for now — the queue and notification + state are in-memory, so multiple replicas won't share state (see Roadmap). + Point startup/readiness/liveness probes at `/health` on the REST port, and use + a restricted security context (non-root, read-only rootfs, seccomp + `RuntimeDefault`, all capabilities dropped). One Service can expose both the + HTTP and gRPC ports. +- **Exposure:** with Gateway API, use an `HTTPRoute` matching the `/api/v1` and + `/health` prefixes and a `GRPCRoute` matching the `notifier.v1.NotifierService` + service. Keeping the two routes' matches disjoint lets REST and gRPC share one + TLS-terminated hostname without shadowing each other; the gateway terminates + TLS and speaks h2c to the pod's plaintext gRPC port. + +**Deploying a change:** ```bash -kubectl apply -f k8s/ +# 1. Build and push a versioned multi-arch image +REGISTRY=registry.example.com/org VERSION=v0.1.5 make docker-build + +# 2. Bump the pinned tag in your GitOps overlay (kustomization.yaml -> newTag) + +# 3. Commit and push — your GitOps controller syncs it ``` -**Included resources:** -- Deployment (3 replicas with rolling updates) -- Services (separate for REST and gRPC) -- ConfigMap (configuration management) -- HPA (auto-scaling 3-10 pods based on CPU/memory) -- Ingress (external access with TLS) -- Secret template (for credentials) - -**Access locally:** +**Access for debugging:** ```bash -kubectl port-forward svc/notifier-rest 8080:8080 -kubectl port-forward svc/notifier-grpc 50051:50051 +kubectl -n port-forward svc/notifier 8080:80 50051:50051 ``` -**Using Kustomize:** -```bash -kubectl apply -k k8s/ -``` +### Reference manifests (`k8s/`) + +The `k8s/` directory in this repo contains **standalone example manifests** +(Deployment, REST/gRPC/metrics Services, ConfigMap, HPA, Ingress, RBAC, secret +template) for trying the service on a generic cluster with +`kubectl apply -k k8s/`. They are illustrative starting points, not a +production reference — a real GitOps deployment will differ (replica count, +Gateway API vs. Ingress, operator-managed secrets vs. plain Secret manifests). ## Architecture