Skip to main content

Two-Node Separated Installation (Datalake / Application)

Overview

This procedure installs the PlantPulse Platform across two servers: a Datalake node and an Application node. Unlike a single-box (FULL) installation, the storage, messaging, and analytics layer runs on one box while the console and batch layer runs on another. Large batch jobs (such as archiving) do not impact console responsiveness, and per-node memory requirements are reduced.

When to use this? This architecture suits environments where a single server has 128GB or less RAM, or when you want to isolate data processing load from console service to improve stability. If a single server is sufficient (recommended 256GB), use the default (FULL) installation from one-line install.

Tier (PP_TIER) Concept

At installation, the PP_TIER environment variable specifies the node's role.

PP_TIERRoleServices Started
FULL (default)Single-box all-in-oneAll services (equivalent to existing installation if unspecified)
DATALAKEDatalake nodeCassandra · PostgreSQL · Kafka · MQTT · Redis · MinIO · Spark · Hive · TSE · CEP · Data Gateway · Temporal · Kestra · Monitor and other infrastructure layer
APPApplication nodeServer (console 80/443) · Batch · Warehouse · OPC-UA · AASX · HA and other application layer
  • PP_TIER is independent of the clustering variable PP_MODE (MASTER/WORKER).
  • All Datalake connections from the APP node (host variables) automatically connect to PP_MASTER_IP (Datalake node IP).

Configuration Files by Node (Copy Targets vs. Per-Node)

In a two-node installation, files in /etc/kopens/ have different roles. What to copy and what not to copy is the most critical point.

File/DirectoryContentsNatureCopy Between Nodes
/etc/kopens/plantpulse-platform.envService secrets sidecar (DB/messaging passwords, etc.)Cluster-sharedCopy
/etc/kopens/ca/Shared cluster CA (CA.crt/CA.key) — TLS trust between nodesCluster-sharedCopy
/etc/kopens/platform.node.envNode topology (PP_TIER, PP_MASTER_IP) — auto-recorded at installationPer-node identityDo not copy

Path verification — The authoritative sidecar secrets location is /etc/kopens/plantpulse-platform.env (permissions 0600). Older installations may have the same name under /opt/kopens/, but it is not read; the installation script restores the canonical location → Environment Variable Reference

  • platform.node.env is auto-created and recorded by stack-run.sh at installation, so the node remembers its tier even after restart or upgrade.
  • Topology (PP_TIER) is kept in a separate file from the secrets sidecar for this reason: the sidecar is copied as-is to the app node, so if tier information were there, the Datalake node's tier would leak into the app node, causing it to install incorrectly as DATALAKE.

Per-Node Specifications

NodeMinimum SpecsNotes
Datalake16 vCPU / 64GB RAM / 500GB+ diskIncrease disk as data volume grows
Application8 vCPU / 48GB RAM / 100GB diskResident footprint ~35GB measured

Both nodes must be on the same network and reach each other (see firewall section below for port list).

Installation Procedure

Step 1 — Install Datalake Node

Run this on the server to be used as Datalake.

sudo -i
export PP_TIER=DATALAKE
curl -fsSL https://product.kopens.io/plantpulse-platform/install.sh | bash
  • The boot gate auto-detects the tier. The Datalake node waits until monitor health (:4950/api/health) reaches OK/WARN, then must pass stack readiness (bin/stack-verify-boot.sh) to be considered successfully installed.
  • When installation completes, a join bundle is auto-generated:
    • /etc/kopens/plantpulse-platform.env — Service secrets (cluster-shared)
    • /etc/kopens/ca/ — Shared cluster CA (TLS trust between nodes)

The Datalake node is the cluster's CA issuing authority. The Application node receives and reuses this CA, so inter-node TLS (CEP event channel) is automatically trusted.

Step 2 — Copy Join Bundle

Copy two items from the Datalake node to the Application node.

# 데이터레이크 노드에서 실행 (<app-ip> = 애플리케이션 노드 IP)
scp /etc/kopens/plantpulse-platform.env root@<app-ip>:/etc/kopens/
scp -r /etc/kopens/ca root@<app-ip>:/etc/kopens/

Warning: Do not copy the /etc/kopens/platform.node.env file. This file holds the node's tier identity (its role). Copy only the two items listed above (Configuration Files by Node).

If you previously installed on an older version, platform.env.generated may contain a remaining export PP_TIER=... line. The latest installation script auto-removes it (migration), but it is safer to delete that line before copying.

Step 3 — Install Application Node

Run this on the Application node. Specify the Datalake node IP in PP_MASTER_IP.

sudo -i
export PP_TIER=APP
export PP_MASTER_IP=<datalake-node-ip>
curl -fsSL https://product.kopens.io/plantpulse-platform/install.sh | bash
  • stack-run.sh auto-applies the join bundle's shared CA (/etc/kopens/ca/) to the pp-security volume before first boot. During the certificate preparation phase, that CA signs this node's certificate and constructs the truststore, so the Datalake node's TLS services (CEP event channel, etc.) are automatically trusted.
  • All Datalake backend connections (Cassandra/PostgreSQL/Kafka/Redis/MinIO/TSE/CEP, etc.) are auto-configured to PP_MASTER_IP.
  • The app node has no monitor (:4950), so the boot gate uses console (:80/status) HTTP 200 response as the readiness criterion.

Firewall (Datalake Node)

The Datalake node must allow connections from the Application node. The simplest method is to add the Application node IP to the firewalld trusted zone.

# 데이터레이크 노드에서 실행
firewall-cmd --permanent --zone=trusted --add-source=<app-ip>
firewall-cmd --reload

Key cross-node ports: 9042 (Cassandra) · 5432 (PostgreSQL) · 9092/9093/9094 (Kafka) · 1883/1884 (MQTT) · 6379 (Redis) · 9000 (MinIO) · 7077 (Spark) · 9083 (Hive) · 10000 (Kyuubi) · 19001 (Gravitino) · 7800/7801 (TSE) · 7400 (CEP) · 5500 (Data Gateway) · 7233 (Temporal) · 4950 (Monitor)

Installation Verification

# 데이터레이크 노드 — 인프라 헬스 (OK 또는 WARN 이면 정상)
curl -kfsS https://127.0.0.1:4950/api/health | jq .status

# 애플리케이션 노드 — 콘솔 상태
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:80/status # 200 이면 정상

Web console access: https://<app-node-ip>successful login is the final confirmation (see Login for initial account).

Cross-Node TLS (Shared CA) Verification

Print the CA fingerprint on both nodes and confirm they match. If fingerprints differ, inter-node TLS trust is broken.

The CA material is in the pp-security volume; read it from a container that mounts that volume. The container you query differs per node — the Datalake node has plantpulse-datalake, the app node does not.

# 데이터레이크 노드에서
docker exec plantpulse-datalake \
openssl x509 -in /var/security/plantpulse/CA.crt -noout -fingerprint -sha256

# 애플리케이션 노드에서 (앱 컨테이너면 무엇이든 같은 볼륨을 읽습니다)
docker exec plantpulse-server-web \
openssl x509 -in /var/security/plantpulse/CA.crt -noout -fingerprint -sha256

Verify zero TLS trust errors (PKIX) in the Application node logs.

# 애플리케이션 노드에서 — 아무 것도 출력되지 않아야 정상
grep -Rl "PKIX" /opt/kopens/plantpulse-platform-docker/logs 2>/dev/null

Datalake Connection Verification

To verify Datalake connectivity from the Application node:

The app container does not have the Datalake's configuration renderer and does not read its env.sh. The only source of truth for values seen by the app is compose, so verify environment variables actually injected into the container.

# 애플리케이션 노드에서 — 백엔드 호스트가 데이터레이크 IP 로 잡혀 있는지
docker exec plantpulse-server-web env | grep -E '_HOST=|MASTER_IP='

If the value is 127.0.0.1, the installation was run without PP_MASTER_IP.

Restart and Upgrade Behavior

  • Tier identity is stored in each node's /etc/kopens/platform.node.env and persists after restart or upgrade. You need not re-specify PP_TIER unless doing a reinstall.
  • Container image upgrades follow the existing procedure per node (update.sh).

Tier Switch and Reinstall Precautions

  • Before reinstalling as single-box (FULL), delete /etc/kopens/platform.node.env first. If this file remains, environment configuration auto-reads it and boots with the previous tier (DATALAKE/APP). An unspecified PP_TIER (FULL) installation does not overwrite this file.

    rm -f /etc/kopens/platform.node.env
  • To convert an APP node to FULL (single-box), perform a clean reinstall. The APP node has never initialized local infrastructure (database schemas, etc.), so remove all containers, volumes, and configuration, then install FULL from scratch (removal procedure is in Docker Installation full removal section).

Troubleshooting

SymptomRoot Cause / Action
APP node service attempts connection to 127.0.0.1PP_MASTER_IP not specified — check node.env and reinstall
Reinstalled but boots with previous tier/etc/kopens/platform.node.env persists — delete and reinstall (Tier Switch and Reinstall Precautions)
App node installs as DATALAKEOlder sidecar with PP_TIER line remains from copy — remove that line from sidecar and reinstall
CEP event TLS error (PKIX)ca/ from join bundle not copied (CA fingerprint mismatch) — redo Step 2, then reinstall APP node
APP node Kafka publish fails (Expiring records)Datalake firewall does not allow APP node, or older installation script — verify firewall, then reinstall with latest script
Login screen shows errorAPP node boot delay in Datalake connection — restart console container (docker compose -f compose/docker-compose.yml restart plantpulse-server-web)