Getting Started Guide
Overview
If you have installed the PlantPulse Platform using the one-liner or Docker installation, all operational scripts are located in the /opt/kopens/plantpulse-platform-docker/bin/ directory. This page guides you on how to start and operate the Platform running as a Docker Compose stack.
The Platform consists of nine containers: one certificate, one data lake, six apps, and one proxy. All nine run continuously. The complete configuration is available in Docker Installation — Installation Layout.
The names on the left below no longer exist. Please use the common verbs on the right.
| Old Name | Use Now |
|---|---|
start.sh | up.sh |
platform-stop.sh | down.sh |
platform-update.sh | update.sh |
platform-remove.sh | remove.sh |
platform-bash.sh | shell.sh |
platform-verify-boot.sh | stack-verify-boot.sh |
worker-run.sh · worker-stop.sh · worker-update.sh · worker-bash.sh | Refer to Worker Management |
stack-run.sh · stack-stop.sh · stack-bash.sh · stack-update.sh · stack-remove.sh still work (they provide a one-line notice of the new name and then perform the same action).
Environment Variable Configuration
Please check the environment variables before starting the Platform. Since resource values are automatically calculated based on the host during installation, there is almost nothing to touch on most servers.
vi /opt/kopens/plantpulse-platform-docker/bin/env.sh
Frequently Adjusted Items
| Variable | Description | Default Value |
|---|---|---|
PP_LANG | Platform locale (ko / en) | en |
PP_TZ | Platform timezone | Asia/Seoul |
DOCKER_PP_CPUS | Number of vCPUs allocated to containers | nproc result |
DOCKER_PP_MEMORY | Memory limit | 90% of host RAM |
DOCKER_DATALAKE_MEMORY | Data lake memory limit | 96G (minimum, does not exceed 90% of host RAM — hosts under 107G are underspecified) |
DOCKER_PP_DATA_DISK_NAME | Data disk name | Automatic backtracking (if failed, sda) |
DOCKER_PP_EXTERNAL_IP | External advertise IP in NAT environments | Empty value |
For a full list of environment variables, please refer to the Environment Variable Reference page.
Applying Changes: After modifying
env.sh, you must restart using./restart.shfor the new settings to take effect.
env.shOn a node where installation is complete, the secret sidecar (/etc/kopens/plantpulse-platform.env) overrides both env.sh and shell exports. For password changes, please use passwd.sh in Password Rotation.
Starting the Platform
Starting After Initial Installation
Once installation (install.sh) is complete, the stack is already running. Please verify the status.
cd /opt/kopens/plantpulse-platform-docker/bin
./status.sh
./ops-check.sh
Starting a Stopped Stack
If the stack has stopped due to ./down.sh or a host reboot, restart it.
cd /opt/kopens/plantpulse-platform-docker/bin
./up.sh
up.sh is idempotent and waits until the system is ready. The exit code 0 does not mean "command succeeded," but rather "now available for use."
| Environment Variable | Default Value | Meaning |
|---|---|---|
PP_READY_TIMEOUT | 900 | Ready wait timeout (seconds) |
PP_READY_INTERVAL | 15 | Check interval (seconds) |
PP_WAIT=0 | — | Do not wait (in this case, 0 does not indicate readiness) |
Data in volumes (pp-data, pp-temp, pp-backup, pp-security, pp-proxy-certs) is preserved. Templates/configurations are managed via host bind mounts (/etc/kopens/conf).
Startup Sequence
Containers start in the order defined by depends_on in compose. Since this is a service_healthy condition, it waits for "available for use" rather than just "process started."
plantpulse-certs (healthy 까지)
│
plantpulse-datalake (healthy 까지)
│
plantpulse-server-web (healthy 까지) ──── plantpulse-proxy
│
plantpulse-batch-web (healthy 까지)
│
├── plantpulse-warehouse
├── plantpulse-plugin-opcua
├── plantpulse-plugin-aasx
└── plantpulse-ha (이 넷은 서로 순서가 없습니다)
Inside the data lake container, infrastructure components start sequentially.
| Order | Category | Component |
|---|---|---|
| 1 | Storage | Valkey(Redis), PostgreSQL, Aster TSDB, RustFS |
| 2 | Analytics | Spark, Hadoop, Hive, Kyuubi, Gravitino |
| 3 | Time Series | time series engine, time series UI |
| 4 | Messaging | Kafka, MQTT |
| 5 | Workflow | Temporal, Kestra |
| 6 | Processing | CEP, Data Gateway, SQL, Monitor |
Process startup itself takes 3–5 minutes (JVM warmup), but a clean installation takes 15–18 minutes until all components stabilize. Aster TSDB schema migration and stabilization are the slowest.
Measured (2026-08-31, 32 vCPU / 128GiB): Data lake 217s, Web server 316s. Restarts with existing data are much faster.
Boot Validation
cd /opt/kopens/plantpulse-platform-docker/bin
./stack-verify-boot.sh
stack-verify-boot.sh evaluates the entire stack, not a single container — it checks if all nine are running·healthy and if the proxy is serving port 443.
up.sh and restart.sh poll until this script passes, which is the basis for why the exit code 0 of these two commands means «available for use».
Verifying Normal Startup
# 서비스 / health / 볼륨 요약 (0 = 정상 / 2 = 비정상)
./status.sh
# 운영 health + 최근 critical log 점검
./ops-check.sh
# 헬스체크 엔드포인트 직접 호출
curl -kfsS https://<server-ip>:4950/api/health | jq
# Docker 상태
docker ps
If all nine are (healthy) in docker ps, the startup is normal.
Stopping the Platform
cd /opt/kopens/plantpulse-platform-docker/bin
./down.sh
Safely stops the stack. Data is preserved in Docker volumes, so restarting with ./up.sh will maintain the previous state.
Caution: Using
docker killor forcing a host shutdown may break data consistency. Always use./down.sh.
Restarting the Platform
cd /opt/kopens/plantpulse-platform-docker/bin
./restart.sh
Gracefully drains internal components, stops the stack in reverse dependency order, restarts them in depends_on order, and waits until they are ready.
Use this for env.sh changes, resolving transient operational issues, or scheduled restarts.
Checking Service Status
Overall Summary
./status.sh
Displays the service list, container status, health results, and volume information all at once. The exit code is the contract — 0 is normal and 2 is abnormal, so it can be used directly for monitoring automation.
Operational Inspection
./ops-check.sh
Inspects container health, health API responses, and recent critical logs. It scans all eight containers.
Host-Side Resource Verification
docker stats --no-stream # 컨테이너별 CPU / 메모리
docker ps # 컨테이너 상태
Since each container has a separate mem_limit, you can identify which container has reached its limit. Per-app limit values are in the Environment Variable Reference.
Accessing Container Internals
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh # 인자가 없으면 데이터레이크
./shell.sh plantpulse-server-web # 특정 컨테이너
Check the list of accessible services with ./status.sh.
shell.sh resolves only services in the base stack by name. Since workers are in the created overlay (compose/docker-compose.worker.yml), access them via docker exec -ti plantpulse-worker-<n> /bin/bash.
Restarting Individual Components
Since containers are separated, there are two ways to restart.
Six Apps — Restart by Container
Since each app runs in its own container, restarting the container is equivalent to restarting that app. Other apps and infrastructure are not affected.
cd /opt/kopens/plantpulse-platform-docker
docker compose -f compose/docker-compose.yml restart plantpulse-server-web
| Container | Running Component |
|---|---|
plantpulse-server-web | Web Console |
plantpulse-batch-web | Batch |
plantpulse-warehouse-web | Data Warehouse |
plantpulse-plugin-opcua | OPC-UA Plugin |
plantpulse-plugin-aasx | AASX Plugin |
plantpulse-ha | Redundancy Recovery Daemon |
docker compose restart does not follow dependency orderIf you need to restart multiple apps together, it is safer to restart the entire stack with ./restart.sh. The startup order is plantpulse-server-web → plantpulse-batch-web → the remaining four.
Components Inside Data Lake — Internal Container Scripts
Infrastructure components such as storage, analytics, and messaging all run within a single plantpulse-datalake container, so you must enter the container and use individual scripts.
# 호스트에서 데이터레이크 진입
./shell.sh
# 컨테이너 내부에서
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd restart storage
exit
| Script | Target |
|---|---|
pd restart storage | Aster TSDB, PostgreSQL, Valkey, RustFS |
pd restart analytics | Spark, Hive, Kyuubi, Gravitino |
pd restart messaging | Kafka, MQTT |
pd restart timeseries | time series engine and UI |
pd restart workflow | Temporal, Kestra |
pd restart cep | Complex Event Processing engine |
pd restart data-gateway | Data Query Gateway |
pd restart admin-api | Admin Console API (was «monitor» until 2026-09-03) |
Only names listed in services/order.txt are accepted — storage · analytics · messaging ·
timeseries · cep · workflow · data-gateway · admin-api. Any other names end with unknown service. SQL query tools (Kyuubi·Hive) do not have a separate script and are included in analytics.
Note: After restarting an infrastructure component, it is recommended to also restart the app containers that depend on that component.
restart-server.sh · restart-batch.sh · restart-warehouse.sh files remain, but they reside in bin/ on the host and only apply to the app's own container. Calling them inside the data lake container will result in a «module not found» error because the app's executable is missing.
restart-opcua-server.sh and restart-aasx-server.sh no longer exist.
OPC-UA and AAS now run in their own containers, plantpulse-plugin-opcua and plantpulse-plugin-aasx respectively; restart the containers directly.
docker restart plantpulse-plugin-opcua
docker restart plantpulse-plugin-aasx
Platform Updates
When a new version is released, run the installation one-liner again on the same server. The new operational scripts, compose files, and images will be deployed, while data remains in the volumes.
sudo -i
curl -fsSL https://product.kopens.io/plantpulse-platform/install.sh | bash
./update.sh is not the official upgrade procedure — it only changes the image and is unaware of services added in the new version. For pre-upgrade steps and verification methods, see Upgrade.
Log Management
Viewing Logs — logs.sh
cd /opt/kopens/plantpulse-platform-docker/bin
./logs.sh # 전체 컨테이너를 한 화면에 (서비스 이름 접두, 시간순)
./logs.sh plantpulse-server-web # 그 컨테이너의 로그
./logs.sh cassandra # 데이터레이크 안 컴포넌트 로그 파일
./logs.sh --list # 볼 수 있는 대상 전체 목록
./logs.sh -n 500 cep # 500줄만
./logs.sh -f plantpulse-server-web # 계속 따라가기 (Ctrl-C 로 종료)
logs.sh prints the last N lines (default 200) and exits. To follow logs continuously, append -f. --no-follow is accepted for compatibility but is now the default, so it is not necessary to add it.
When a problem occurs, it is often difficult to know which container is affected. Running without arguments mixes the logs of all eight containers chronologically, preventing you from missing the cause by watching only one container.
--list reads the service list from compose and the component log directories from the data lake container directly. It shows the actual list at that moment, not a manually managed list.
Internal Container Log Directories
Log paths for components inside the data lake container. (Verify after entering via ./shell.sh)
| Module | Log Path |
|---|---|
| Valkey | plantpulse-storage/cache/valkey/logs/system.log |
| PostgreSQL | plantpulse-storage/db/postgres/logs/system.log |
| Aster TSDB | plantpulse-storage/db/cassandra/logs/system.log |
| RustFS | plantpulse-storage/object/rustfs/logs/system.log |
| Gravitino | plantpulse-analytics/gravitino/logs/system.log |
| Hive | plantpulse-analytics/hive/logs/system.log |
| Spark | plantpulse-analytics/spark/logs/system.log |
| Kyuubi | plantpulse-analytics/kyuubi/logs/system.log |
| time series engine | plantpulse-timeseries/engine/logs/system.log |
| Kafka | plantpulse-messaging/kafka/logs/server.log |
| MQTT | plantpulse-messaging/mqtt/logs/hivemq.log |
| Temporal | plantpulse-workflow/temporal/logs/system.log |
| Kestra | plantpulse-workflow/kestra/logs/system.log |
| CEP | plantpulse-cep/logs/system.log |
| Data Gateway | plantpulse-data-gateway/logs/system.log |
| Admin Console API | plantpulse-datalake-admin-api/logs/system.log |
The paths are based on /opt/kopens/plantpulse-platform/. Since logs for the six apps are in their respective containers, it is faster to view them via ./logs.sh <컨테이너>.
Copying Logs to Host
cd /opt/kopens/plantpulse-platform-docker/bin
./tools/copy-log-to-local.sh
Troubleshooting
cd /opt/kopens/plantpulse-platform-docker/bin
./doctor.sh
Creates a diagnostic tarball (/tmp/pp-doctor-<호스트>-<타임스탬프>.tar.zst). It contains the status, health probe output, logs, and configurations of all containers, as well as the host environment, with passwords and keys masked. It does not change the system.
Sending the generated tarball to the KOPENS technical support team enables rapid analysis.
Worker Management (Cluster Environment)
If you need to expand throughput while operating with a single master node, add worker containers. The authoritative list of workers is in compose/workers.roster (one per line, <id> <ip>), and the overlay compose file is generated from here.
cd /opt/kopens/plantpulse-platform-docker
# 추가 — roster 등록 → 오버레이 재생성 → 볼륨 → pull → up → 링 조인 확인
bin/worker-add.sh # 빈 id·주소 자동 선택
bin/worker-add.sh 3 # id 지정
bin/worker-add.sh 3 10.99.0.103 # id·주소 지정
# 진입
docker exec -ti plantpulse-worker-3 /bin/bash
# 제거 — 반드시 이 순서
bin/worker-decommission.sh 3 # 데이터 이관 + 링 이탈 확인 + 복제 슬롯 정리
bin/worker-remove.sh # 그 다음에 컨테이너 제거
docker rm on a live worker is «abandonment», not removalAster TSDB continues to hold the token range and host ID of that node (if RF=3, QUORUM is maintained and no alarms will trigger), and the master will not release the PostgreSQL physical replication slot for that worker, fixing WAL until the disk is full. You must run worker-decommission.sh first — worker-remove.sh will be rejected if the container is running.
worker-decommission.sh calls pd node rf <남는 수> internally first. You only need to manage the order manually if you are typing pd node remove manually → pd node rf.
:::
worker-run.sh · worker-stop.sh · worker-update.sh · worker-bash.sh were deleted on 2026-08-31. They were based on manually managed worker lists and were removed when switching to the roster method. They are replaced by worker-add.sh (including pull), compose verbs, compose pull+up -d, and docker exec respectively.
For more details, please refer to the Cluster Installation page.
Initial Access After Installation
| Item | Value |
|---|---|
| Web Console URL | https://[서버IP] (80/443) |
| Admin UI URL | https://[서버IP] (Same address as Web Console) |
| Monitor UI URL | https://[서버IP]:4950 |
| Default Admin ID | admin |
| Default Password | admin123! |
Security Notice: It is recommended to change the default password after the first login for security. → Initial Password
Node Management Scripts (Inside Data Lake Container)
Aster TSDB and database management are handled by the pd CLI (/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd) inside the plantpulse-datalake container. Please enter via ./shell.sh before use.
Aster TSDB Management
| Script | Description | When to Use |
|---|---|---|
pd node status | Check cluster status | Regular inspection, when verifying issues |
pd node info | Node detailed information | When checking node configuration |
pd node compact | Execute manual compaction | When reclaiming disk space |
pd node compactionstats | Check compaction progress | During performance inspection |
pd node flush | Memtable flush | When clearing memory |
pd node drain | Node Drain (Prepare for safe shutdown) | Before shutting down a node |
pd node repair | Node data recovery/synchronization | In case of data inconsistency |
pd node repair-table | Recover specific table | Table-level recovery |
pd node cleanup | Node cleanup (Delete unnecessary data) | After node changes |
pd node remove | Remove node from cluster | When releasing a node — after lowering RF with pd node rf |
pd node rf [--check] [노드수] | Adjust replication factor for all keyspaces to match ring | When adding or removing nodes |
pd node add | Add node to cluster | During expansion |
pd node upgrade | Upgrade node | During version upgrade |
pd node tpstats | Thread pool statistics | During performance analysis |
pd node proxyhistograms | Proxy histogram | During latency analysis |
pd node table-histograms | Table histogram | Table performance analysis |
pd node table-stats | Table statistics | Verifying data size/count |
pd node sstable-size | Check SSTable size | Verifying disk usage |
pd node cache-clear | Reset cache | When cache issues occur |
pd node topic | Kafka topic management | During messaging inspection |
pd node disk | Check disk usage | During capacity inspection |
pd node errors | Check error logs | During error diagnosis |
pd node train-zstd | ZStandard compression training | During compression optimization |
pd node init-cms | CMS initialization | During initial setup |
Database Access
| Script | Description |
|---|---|
pd node psql | Access PostgreSQL shell (Metadata DB) |
pd node cql | Access Aster TSDB CQL shell (time series DB) |
Summary of Frequently Used Commands
cd /opt/kopens/plantpulse-platform-docker/bin
./preflight.sh # 설치 전 비파괴 사전 점검
./install.sh # 최초 설치 (OS+Docker+방화벽+스택)
./up.sh # 기동 — 준비될 때까지 대기 (0 = 준비 완료)
./down.sh # 정지 (상태 보존)
./restart.sh # graceful 재시작 (drain + 준비 대기)
./status.sh # 서비스 / health / 볼륨 요약 (0=정상 / 2=비정상)
./logs.sh [서비스] # 로그 보기 — 1회 출력. -f 로 따라가기 (인자 없으면 전체, 목록은 --list)
./shell.sh [서비스] # 컨테이너 bash 진입
./ops-check.sh # 운영 health + critical log 점검
./remove.sh # 컨테이너 제거 (볼륨은 보존)
./backup.sh # 볼륨 백업 (기본 pp-data · pp-security)
./doctor.sh # 장애 진단 tarball 생성
./passwd.sh --list # 바꿀 수 있는 비밀번호 목록
./stack-verify-boot.sh # 스택 전체 준비 판정
All verbs support --help.