Ports
Every port a ScramDB node listens on, what it carries, the setting that moves it, and who has to reach it. The Docker image exposes all six. The Helm chart declares every port a pod's node opens on the pod and publishes it on the headless Service.
| Port | Carries | Set by | Reached by | Open when |
|---|---|---|---|---|
5432 | The PostgreSQL wire protocol: every client connection | [general] pg_address or --pg-address | Clients: your applications, psql, drivers | Always |
9090 | Prometheus metrics at /metrics, a health check at /health | [general] metrics_port or --metrics-port; 0 turns it off | Your monitoring and load balancer health checks | Always, unless set to 0 |
7190 | The cluster transport's control traffic: membership, consensus, the commit protocol, forwarded DDL and lock calls | [cluster] cluster_listen | Every other node of the cluster, in both directions | Cluster mode only |
7191 | The cluster transport's interactive traffic: replies to forwarded point reads | [cluster] cluster_interactive_listen, by default the control port plus one | Every other node, in both directions | Cluster mode only |
7192 | The cluster transport's bulk traffic: query data exchange, fragment dispatch, snapshot transfer, the rows a cluster COPY stages | [cluster] cluster_bulk_listen, by default the control port plus two | Every other node, in both directions | Cluster mode only |
9191 | The Semantic AI MCP server for AI agents | Fixed: the scramdb/semantics package may listen on this port only | AI agents and MCP hosts | While the package is installed and [udf.daemon] enabled (both the default in the Docker image) |
Clients only ever need 5432. A cluster adds nothing on the client side: any node answers on its
own 5432 (see Connecting to a cluster).
Bind addresses
5432binds127.0.0.1when the engine runs with no flag and no config. The Docker image starts it with--pg-address 0.0.0.0:5432, and the Helm chart setspg_address = "0.0.0.0:5432", because a container's loopback cannot be reached from outside it.pg_addressin the config file wins over--pg-address.9090always binds every interface, whateverpg_addresssays, and has no authentication.7190to7192bind the address incluster_listen(0.0.0.0by default). Peers dial the host inadvertise_addron the control port and learn the other two ports over that connection, so all three must be open between every pair of nodes. With the interactive and bulk addresses left unset, a taken port moves that lane to a port the kernel picks, with a warning in the log; a firewall or a network policy would not let that port through. The shipped Docker template, Kubernetes manifests and Helm chart set all three addresses, so a taken port stops the node's start with an error instead.9191bindsMCP_HOST:127.0.0.1on a plain install,0.0.0.0in the Docker image. It has no HTTP authentication unlessMCP_AUTH=basic, which the Helm chart sets; see Semantic AI.
Moving the cluster ports
Set the control port and the other two follow it:
[cluster]
cluster_listen = "0.0.0.0:17190" # interactive 17191, bulk 17192
advertise_addr = "10.0.0.1:17190"
seeds = ["10.0.0.2:17190", "10.0.0.3:17190"]
Set cluster_interactive_listen and cluster_bulk_listen as well to choose those two freely.
The three must be distinct. Two nodes on one host need different ports for all three.
Firewall rules
| From | To | Ports |
|---|---|---|
| Applications | Every node, or the load balancer in front of them | 5432 |
| Monitoring | Every node | 9090 |
| Every node | Every other node | 7190, 7191, 7192 |
| AI agents | The nodes they use | 9191 |
Nothing else speaks the cluster protocol: allow 7190 to 7192 from the cluster's own nodes only,
and turn on TLS between cluster nodes, which covers all
three. Production hardening lists the rest.
Where each deployment sets them
- Docker: the image exposes every port. A single node publishes the ones it serves
(
-p 5432:5432 -p 9090:9090 -p 9191:9191); cluster nodes reach each other on a shared Docker network and publish only the client, metrics and MCP ports. See Docker and Quick Start. - Kubernetes: the chart declares the six ports on every pod and publishes them on the headless
Service;
service.*decides which the client Service carries, andnetworkPolicy.enabledlets the three transport ports through between the chart's own pods only. See Kubernetes. - Bare metal or VMs: open the firewall rules above; see Forming a cluster.