System Requirements
This guide outlines the hardware, OS, and network requirements for stable operation of the PlantPulse Platform. It is based on validated standard environments.
Requirements at a Glance
| Category | Minimum (Dev / Test) | Standard (Production) | Large Scale |
|---|---|---|---|
| CPU | 16 vCPU | 32 vCPU | 48+ vCPU |
| Memory | 64 GB | 128 GB | 256 GB+ |
| OS Disk | 200 GB | 256 GB | 512 GB |
| Data Disk | 200 GB (SSD) | 1 TB (NVMe SSD) | 4 TB+ (NVMe SSD) |
| Network | 1 Gbps | 1 Gbps | 10 Gbps |
| OS | RHEL/Rocky/Oracle 8.x | RHEL/Rocky/Oracle 9.x | Same |
| JDK | OpenJDK 21 LTS | OpenJDK 21 LTS | OpenJDK 21 LTS |
Validated Environment: The production reference dev server runs 48 vCPU / 188 GB RAM / 4.8 TB NVMe SSD / RHEL 9 / Temurin OpenJDK 21.0.11 LTS.
Hardware
CPU
- Recommended: 32 vCPU or more (Intel Xeon, AMD EPYC, ARM Graviton, etc.)
- The IIoT engine uses a 36-thread pipeline (
engine.pipeline.threads) - Spark distributed analytics uses additional resources (
PP_CLUSTER_CORES) - More cores increase concurrent message throughput
Memory
- 128 GB minimum · 256 GB recommended for production
- Memory directly affects Cassandra and Kafka performance via page cache
- Cassandra heap: 1/4 of host memory (max 32 GB)
- Container memory limit: up to 90% of host memory via
DOCKER_PP_MEMORY
Disk
Recommended: separate OS and data disks — Separating the OS disk (
/) from the data disk (/data1) simplifies backup, expansion, and fault isolation.
/ # OS 디스크 (256 GB)
└── opt/kopens/ # PlantPulse 바이너리 설치
/data1/ # 데이터 디스크 (1 TB+ NVMe SSD)
├── pp-data/ # Cassandra · PostgreSQL · MinIO · Valkey
├── pp-temp/ # Spark / 처리 임시
└── pp-backup/ # 백업 산출물
| Mount | Capacity | Disk Type | Purpose |
|---|---|---|---|
/ | 256 GB | SSD | OS, binaries |
/data1 | 1 TB+ | NVMe SSD required | Main data |
/data2 ~ /dataN | 1 TB+ | NVMe SSD | (Optional) Cassandra data / commitlog separation |
Cassandra Disk Optimization (Advanced)
In large-scale environments, separating commitlog and data onto separate disks significantly improves write throughput.
/data1/pp-data/cassandra/data/ # SSTable (대용량 NVMe)
/data2/pp-data/cassandra/commitlog/ # commitlog (별도 NVMe, sync I/O)
Operating System
Supported OS
| OS | Version | Validated | Recommended |
|---|---|---|---|
| Oracle Linux | 8.x, 9.x | ✓ | Recommended |
| RHEL | 8.x, 9.x | ✓ | Recommended |
| Rocky Linux | 8.x, 9.x | ✓ | Recommended |
| AlmaLinux | 8.x, 9.x | ✓ | |
| Ubuntu | 20.04+ | ✓ | |
| Amazon Linux | 2, 2023 | ✓ |
All subsequent instructions are based on RHEL/Rocky/Oracle 9.x. When using Ubuntu or Amazon Linux, adapt only the package commands (
apt/yum) to your environment.
Java (JDK)
PlantPulse is based on Java 21 LTS. setup.sh / tools/java/ install it automatically.
$ java -version
openjdk version "21.0.11" 2026-04-21 LTS
OpenJDK Runtime Environment Temurin-21.0.11+10 (build 21.0.11+10-LTS)
If manual installation is required:
# RHEL/Rocky/Oracle
dnf install -y java-21-openjdk java-21-openjdk-devel
# Ubuntu
apt-get install -y openjdk-21-jdk
The JAVA_HOME environment variable is registered automatically, and all modules apply it through JAVA_TOOL_OPTIONS="-Duser.language=${PP_LANG} -Duser.timezone=${PP_TZ}".
Network / Hostname
Hostname
hostnamectl set-hostname plantpulse-prod-01
# /etc/hosts
vi /etc/hosts
# 첫 행 직후에 추가:
# 192.168.0.41 plantpulse-prod-01 plantpulse-prod-01.local
Static IP
If the server IP changes, cluster and client connections will break. Always use a static IP.
# NetworkManager (RHEL 9+)
nmcli con mod ens33 ipv4.method manual \
ipv4.addresses 192.168.0.41/24 \
ipv4.gateway 192.168.0.1 \
ipv4.dns "168.126.0.1 8.8.8.8"
nmcli con up ens33
Time Synchronization (Required)
Distributed components (Cassandra, Kafka, etc.) are sensitive to time accuracy between nodes.
dnf install -y chrony
systemctl enable --now chronyd
chronyc tracking # 동기화 상태 확인
chronyc -a makestep # 즉시 동기화
OS Tuning (Required)
The following values are automatically applied by install.sh (one-line / Docker installation). In manual environments, configure them identically yourself.
File Descriptors / Process Limits
# /etc/security/limits.conf
* - memlock unlimited
* - nofile 1048576
* - nproc 32768
* - as unlimited
Kernel Parameters
# /etc/sysctl.conf (install.sh 자동 적용)
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 10
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 1024
vm.max_map_count = 1048576
vm.overcommit_memory = 0
fs.file-max = 1048576
sysctl -p /etc/sysctl.conf
Disable Swap
Database and Java processes must avoid swap.
swapoff --all
# /etc/fstab 의 swap 라인 주석 처리
sed -i '/swap/s/^/#/' /etc/fstab
SELinux
setup.sh automatically switches to permissive. To change manually:
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
Native Libraries
Libraries for improving Cassandra performance.
dnf install -y jna jemalloc jemalloc-devel zstd libpq
Disk I/O Tuning
NVMe SSD
# /etc/udev/rules.d/60-ioscheduler.rules
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
# 즉시 적용
udevadm trigger
HDD (Not Recommended for Production)
echo mq-deadline > /sys/block/sdb/queue/scheduler
blockdev --setra 128 /dev/sdb
Firewall
install.sh enables firewalld (systemctl enable --now firewalld) and automatically opens ports required by the Platform. Only use SKIP_FW=1 to skip this step if the firewall is managed externally (corporate firewall / cloud security group).
Example of manual opening in a manual environment:
systemctl enable --now firewalld
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=7443/tcp
firewall-cmd --permanent --add-port=4950/tcp
firewall-cmd --permanent --add-port=1883/tcp
firewall-cmd --permanent --add-port=1884/tcp
firewall-cmd --permanent --add-port=9092/tcp
firewall-cmd --permanent --add-port=9094/tcp
firewall-cmd --reload
See Port Configuration for the complete port list.
Upper-layer firewall / cloud security group: Corporate and cloud firewalls are separate and must be configured to allow traffic as well. For private ranges (RFC 1918, Tailscale CGN), restricting source by trusted IP is recommended.
External Access / Exposure Recommendations
| External Exposure | Port | Recommended |
|---|---|---|
| Web console | 80, 443, 7443 | Recommended via nginx/HAProxy |
| Health check | 4950 | Monitoring systems only (HTTPS) |
| MQTT (external devices) | 1884 (TLS), 18884 | TLS recommended |
| Kafka external clients | 9094 (TLS) | TLS required |
| Data gateway | 5500 | API Key + TLS |
Restrict DB / messaging PLAINTEXT ports and JMX to private network only.
Supported Browsers
The web console supports current standard browsers.
| Browser | Minimum Version | Recommended |
|---|---|---|
| Google Chrome | 100+ | Recommended |
| Microsoft Edge | 100+ | ✓ |
| Firefox | 100+ | ✓ |
| Safari | 15+ | ✓ |
Pre-Installation Checklist
Verify the following before installation:
- CPU 16+ vCPU, memory 64+ GB, data disk 200+ GB
- Data disk mounted on separate
/data1 - OS RHEL/Rocky/Oracle 8+ or Ubuntu 20.04+
- Static IP configured
-
chronydenabled (time synchronization) - Hostname and
/etc/hostsregistered - Swap disabled
-
nofile 1048576and other limits applied -
vm.max_map_countand other sysctl applied - Firewall policy clear (external exposure ports defined)
- DNS working properly (
getent hosts <hostname>) - Internet access or air-gapped network bundle ready
Next Steps
- Quick installation → One-Line Installation (Recommended)
- Container-based installation → Docker Installation
- Direct host installation → Binary Installation
- Check port conflicts → Port Configuration