# 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**.