diff --git a/docs/deploy-notes.md b/docs/deploy-notes.md new file mode 100644 index 0000000..9954a51 --- /dev/null +++ b/docs/deploy-notes.md @@ -0,0 +1,94 @@ +# OPC Gateway — Deploy Notes (SIENTIAPDE-1972) + +This repo has no Dockerfile and no `values/` directory — that's by design (see +below). This doc captures what the Helm, container-images, and platform repos +need to know to deploy the gateway. Cross-reference: +`docs/superpowers/specs/2026-07-13-opc-gateway-design.md` (§9/§10/§12). + +## Entrypoint & image + +- Runs as `ingestor.app` (`PYTHON_APP` entrypoint), cloned from Gitea at pod + start onto the shared **`sientia-module`** base image (Python 3.11+). +- No repo-local Dockerfile: images are centralized in + `sientia-container-images`. +- New pip deps that must be present in the image / library distribution + (see `requirements.txt`): + - `nats-py>=2.6` + - `grpcio>=1.60` + - `grpcio-tools>=1.60` + - the `sientia_do` release that includes SIENTIAPDE-1590 (generic + Mongo/MinIO/Postgres methods used by the gateway). + +## Env (new since the ingestor) + +From `.env.example`, `# OPC Gateway` block: + +- `NATS_URL` +- `NATS_WRITE_SUBJECT` +- `NATS_QUEUE` +- `GRPC_ENABLED` +- `GRPC_PORT` +- `CERT_BUCKET` +- `CERT_CACHE_DIR` +- `WRITE_TIMESTAMP` +- `WRITE_QUALITY` +- `WRITE_MIN_PAUSE_S` +- `IDLE_CONN_MAX_S` + +Plus MinIO (client cert storage) and Postgres (`write_status` updates): + +- `MINIO_ENDPOINT`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `MINIO_SECURE` +- `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, + `POSTGRES_DBNAME`, `POSTGRES_MIN_CONNECTIONS`, `POSTGRES_MAX_CONNECTIONS` + +## Health probe + +Exec probe (platform DataOps standard): + +``` +curl -sf http://localhost:9090/metrics | grep -q '^app_up{.*} 1' +``` + +Verified: `ingestor/app.py` sets `metrics.APP_UP.labels(pod_id=...).set(1)` +right after `start_http_server(HTTP_METRICS_PORT, default 9090)` in +`start_prometheus_server()`, and `.set(0)` on shutdown in the main loop's +`finally`/exit path. A runtime check (prometheus_client HTTP server, gauge +set to 1, scraped over HTTP) produced the exposition line +`app_up{pod_id="x"} 1.0`, which matches the probe regex. + +## waitForDependencies + +Init-container wait list: **Gitea, MongoDB, Redis, Postgres, MinIO, NATS**. + +NATS is also tolerated at runtime: the app starts even if NATS is +unreachable and the `nats-py` client retries/reconnects internally +(`ingestor/adapters/nats_consumer.py` — no custom reconnect logic, relies on +nats-py's built-in reconnection); only the first connection failure should +raise a notification, not every retry. + +## NetworkPolicy + +- Egress: Mongo, Redis, Postgres, MinIO, NATS, OPC servers (port 4840). +- Ingress: Prometheus scrape on 9090. +- gRPC port (default 50051): **internal-only**, no auth — there is no + consumer yet. Only add an ingress rule when a real caller appears, per the + feature owner (Vitor Pimentel). + +## Cert cache + +- `CERT_CACHE_DIR` (default `/tmp/opc-certs`) must be writable — + `emptyDir`/tmpfs, since the pod root filesystem is read-only. +- Certs are sourced from MinIO bucket `sientia-dataops` + Mongo collection + `platform_certificates`. + +## ServiceMonitor + +- Label `release: kube-prometheus-stack`. + +## Cross-repo integration gates + +- Subscription v2 + gRPC persist land at **SIENTIAPDE-1974** (Orchestrator). +- `write_status` column via Flyway (`sientia-dataops-database-migrations`) + + the Laborious DataFrame change land at **SIENTIAPDE-1975**. +- NATS broker provisioning on the air-gapped platform is + **SIENTIAPDE-1985**.