Skip to main content

Port Configuration Reference

PlantPulse operates as a Docker Compose stack, with each container maintaining its own ports. Both single-server and cluster deployments follow the same port design.

«Firewall is open» and «actually open on the host» are different things

The ports bound to the host are determined by compose/docker-compose.yml's ports:. The firewall list that install.sh opens is broader. Having a port in the firewall does not mean a response comes back on that port.

The first table on this page shows all ports actually open on the host. All other ports work only inside containers.

Which container opens what

ContainerPorts open to host
plantpulse-proxy80 · 443 · 1883 · 1884 — the only gateway users and equipment touch
plantpulse-plugin-opcua-server11004 · 11005
plantpulse-ha10210
plantpulse-datalakeAll infrastructure tier (table below)
plantpulse-server-web · plantpulse-batch-web · plantpulse-warehouse · plantpulse-plugin-aasx-serverNone — operate only behind the proxy
plantpulse-certsNone (one-shot)

Port topology

PortContainerProtocolPurposeRecommended
80proxyHTTPOperations console / REST APIReverse proxy recommended
443proxyHTTPSOperations console / REST API (TLS)
7443datalakeHTTPSAdmin console
4950datalakeHTTPSMonitor UI + /api/healthMonitoring systems
1883proxyTCPMQTT plaintext — Edge device / sensor collectionPrivate network recommended
1884proxyTCP+TLSMQTT over TLS (proxy passthrough, broker end-to-end)TLS recommended
11004 / 11005opcua-serverOPC-UAExternal equipment endpointTLS recommended
10210haHTTPHA daemon /api/health · /api/cluster — peers connect in 2-cluster setupPeer IP only
9094datalakeTCP+TLSKafka external clientsTLS required
5500 / 5501datalakeHTTP / HTTPSExternal system data queriesAPI Key

Operations recommendation: expose only 80/443 to the outside; keep all others on private networks.

Web console real-time push needs no separate port

Real-time push goes through the proxy (443). No separate WebSocket port is opened to the host.

Messaging

PortContainerProtocolPurpose
1883 / 1884proxyTCP / TLSMQTT (HiveMQ). proxy publishes
18883 / 18884datalakeTCP / TLSReserved. No listeners on these ports currently
9092datalakeTCPKafka PLAINTEXT (private network only)
9093datalakeTCPKafka KRaft controller
9094datalakeTCP+TLSKafka SASL_SSL
Kafka bypasses the proxy

Kafka clients, after bootstrap, reconnect to the address that advertised.listeners provides. A proxy in front requires rewriting that address too, and if wrong, bootstrap succeeds but then fails silently. Therefore, Kafka ports are published directly by the datalake.

STOMP (ActiveMQ) is retired

With browser real-time push moving to SSE, the STOMP broker was removed from the datalake image. 61000 / 61004 are no longer serviced. Clean up any old firewall rules mentioning them.

Storage (private network only)

PortProtocolPurpose
9042CQLCassandra
7000 / 7001TCPCassandra Gossip / SSL
5432TCPPostgreSQL
6379TCPValkey (Redis-compatible)
6380TCP+TLSValkey TLS listener
9000HTTPMinIO API
9001HTTPMinIO Console

Analytics / SQL (private network only)

PortProtocolPurpose
7077TCPSpark Master RPC
4440HTTPSpark Master UI — not 8080
8081HTTPSpark Worker UI
10000ThriftKyuubi SQL Gateway
10099HTTPKyuubi REST API
19001HTTPGravitino unified catalog
9083ThriftHive Metastore
3500 / 3600HTTPLab analytics environment
4000 / 4001HTTP / HTTPSSQL query service

Processing / Time series (private network only)

PortProtocolPurpose
7400 / 7401HTTP / HTTPSCEP (Esper)
7800 / 7801HTTP / HTTPSTime series engine (TSE)
3000HTTPGrafana dashboard
5500 / 5501HTTP / HTTPSData Gateway

Workflow (private network only)

PortProtocolPurpose
7233gRPCTemporal Frontend
8233HTTPTemporal Web UI
8380HTTPKestra (UI + API)
8381HTTPKestra management port

Other datalake ports

PortPurpose
7003Diagnostics console (private network only)
60000 / 60001OPC Agent data collection (private network only)
6199 / 6299 / 6399 / 6499 / 7099JMX agent — allow management node IP only
9500 · 9501 · 9600 are no longer exposed to the host

9500 / 9501 were Tomcat in plantpulse-batch-web, and 9600 was the web server in plantpulse-warehouseapp tier. Definitions from when batch and warehouse lived in the same container as datalake lingered on the datalake side but have been cleaned up.

Both applications run in their own containers and do not open host ports; check their status via bin/status.sh and bin/logs.sh <컨테이너> instead. If these three ports remain in old monitoring settings, remove them.

Container-internal only (not exposed to host)

The following ports work only inside containers. Querying them from the host via curl gets no response.

PortTargetCheck instead
8090 · 4800 / 4801AAS (BaSyx) V3 API · V2 Registry/AASContact reverse proxy separately if external access is needed
7199 · 7279Cassandra · HiveMQ JMXEnter datalake via bin/shell.sh to inspect
App ports of server, batch, warehouseEach app container internalbin/status.sh / bin/logs.sh <컨테이너>
4949 is plaintext

Console and health API are serviced on both ports4950 (HTTPS) and 4949 (plaintext HTTP). Same console, same API, scheme only differs. 4949 no longer redirects to 4950.

4949 is plaintext — login passwords and session cookies flow unencrypted. On untrusted networks, use 4950. Port 4949 exists as an option for environments where self-signed certificate warnings actually block operators.

# 호스트 / 외부에서
curl -kfsS https://<server-ip>:4950/api/health | jq

# 컨테이너 안에서 (어떤 구성에서도 동작합니다)
docker exec plantpulse-datalake curl -kfsS https://127.0.0.1:4950/api/health | jq

Check for port conflicts before installation

# 핵심 포트 점유 확인
ss -tlnp | grep -E ':(80|443|1883|1884|3000|4000|4950|5432|5500|6379|7077|7233|7400|7443|7800|8233|8380|9000|9042|9092|10000|10210|11004|19001)\s'

No output means no conflicts. If there is output:

# 점유 프로세스 확인
sudo lsof -i :<port>
sudo ss -tlnp | grep ":<port>"

Frequently conflicting ports: 80 (Apache/Nginx), 5432 (external PostgreSQL), 3000 (Grafana/Node.js), 9092 (external Kafka), 6379 (external Redis). If you run external services, moving their ports is simpler.

bin/preflight.sh performs non-destructive inspection of major ports (80 · 443 · 7443 · 4949 · 4950) before installation.

Firewall setup examples

install.sh automatically configures host firewall (firewalld / ufw). Below are examples for when you must allow ports directly on an upstream firewall (corporate network, cloud security group, router).

firewalld (RHEL/Rocky/Oracle)

# 외부 노출 (모든 IP)
for port in 80 443 7443 4950; do
firewall-cmd --permanent --add-port=${port}/tcp
done

# 외부 노출 (TLS 메시징 / 설비)
for port in 1884 9094 11004 11005; do
firewall-cmd --permanent --add-port=${port}/tcp
done

# 사설망 only (RFC 1918 + Tailscale CGN 허용)
for src in 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10; do
for port in 1883 5432 6379 7077 7233 7800 8233 8380 9000 9001 9042 9092 10000 10210 19001; do
firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=${src} port port=${port} protocol=tcp accept"
done
done

firewall-cmd --reload

ufw (Ubuntu)

# 외부 노출
for port in 80 443 7443 4950 1884 9094 11004 11005; do
ufw allow ${port}/tcp
done

# 사설망 only
for port in 1883 5432 6379 7077 7233 7800 8233 8380 9000 9042 9092 10000 10210 19001; do
for src in 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10; do
ufw allow from $src to any port $port
done
done

ufw enable

Verify automatic configuration

# RHEL/Rocky/Oracle
sudo firewall-cmd --list-ports
sudo firewall-cmd --list-rich-rules

# Ubuntu
sudo ufw status numbered

Cloud security groups (e.g., AWS / GCP / Azure)

Cloud security groups must be configured identically alongside host firewall rules.

Inbound ruleSourcePort
Operations console0.0.0.0/0 (or company IP)80, 443, 7443
Health checkMonitoring node4950
MQTTDevices1883, 1884
OPC-UAEquipment11004, 11005
Kafka TLSExternal clients9094
Private networkVPC CIDR1883, 5432, 6379, 7077, 9042, 9092, 10000, 10210, …