Troubleshooting
This document guides you through common issues and solutions for the PlantPulse Platform operated via a one-line / Docker installation. Most issues can be resolved by following the procedures below in order.
The platform runs as a Docker Compose stack — one certificate one-shot (plantpulse-certs, Exited (0) is normal), one data lake, six apps, one proxy. There is no container named plantpulse-platform.
Narrow down "what is broken" first. ./status.sh answers per service → Installed Shape
First step: Whatever the issue, please check the following 3 things first.
cd /opt/kopens/plantpulse-platform-docker/bin./status.sh # Container / health / volume summary./ops-check.sh # Operational health + critical log./logs.sh -n 200 # Recent container logs (all)If this doesn't resolve the issue, generate a diagnostic tarball with
./doctor.shand share it with technical support.
Container Startup Issues
Symptom: Container stuck in unhealthy state and doesn't recover
| Cause | Solution |
|---|---|
| Cassandra schema migration failure | Check the error with ./logs.sh cassandra -n 300, then retry with ./restart.sh. If it keeps failing, ./doctor.sh |
| Data directory permission issue | Check the permissions on the host's /data1/pp-data. sudo chown -R root:root /data1/pp-data && sudo chmod -R 755 /data1/pp-data |
| Out of memory (OOMKilled) | Check with docker inspect <컨테이너> --format '{{.State.OOMKilled}}'. Limit values differ per container — data lake is DOCKER_DATALAKE_MEMORY, apps are DOCKER_SERVER_MEMORY, etc. (Environment Variables) |
| JVM warm-up incomplete | Boot takes 3–5 minutes. If unhealthy persists beyond 5 minutes, proceed to next-level diagnosis |
# 어떤 서비스가 비정상인가 (0 = 정상 / 2 = 비정상)
./status.sh
# 스택 전체 준비 판정
./stack-verify-boot.sh
# 컨테이너별 메모리 / CPU
docker stats --no-stream
# 헬스체크 엔드포인트 응답 확인
curl -kfsS https://<server-ip>:4950/api/health | jq
plantpulse-certs bakes certificates and then finishes on its own, so Exited (0) is the success state. Because compose has explicitly disabled the healthcheck for this container (healthcheck: disable), the health column stays blank, and a normally functioning container is never shown as unhealthy. status.sh and ops-check.sh judge only this container by its exit code, so please look at it the same way manually.
Symptom: no such service · reports that the container doesn't exist
The initial installation was not completed, or the container was removed via ./remove.sh.
If you were following an old runbook looking for plantpulse-platform, there is no container by that name — check names with ./status.sh or ./logs.sh --list.
cd /opt/kopens/plantpulse-platform-docker/bin
./install.sh # 최초 설치
# 또는 OS 설정이 이미 끝났다면
./up.sh # 컨테이너 생성 + 기동
Symptom: address already in use (port conflict)
An older version of plantpulse is running natively on the host, or another service is occupying the port.
# 호스트 native plantpulse 정지
pkill -ef plantpulse
# 특정 포트 점유 프로세스 확인 (예: 7500)
ss -tlnp | grep :7500
# 충돌 프로세스를 종료한 후 재시도
./restart.sh
For a detailed port list, see Port and Service Management.
Image / Registry Issues
Symptom: docker pull → unauthorized: authentication required
Registry authentication has expired or credentials are missing.
docker login docker.kopens.io
# Username/Password 입력 후
./update.sh
Symptom: Image download failure (network)
# 1. 레지스트리 접근 가능 여부 확인
curl -fsSL https://docker.kopens.io/v2/
# 2. DNS 확인
nslookup docker.kopens.io
# 3. 회사 방화벽 / 프록시 차단 가능성 — 네트워크 관리자에게 다음 도메인 허용 요청
# docker.kopens.io, download.kopens.io
If you're in an air-gapped network, follow the Airgap installation procedure on the Docker Installation page.
Database Issues
Database components run inside the container. Inspection is performed after entering the container with ./shell.sh.
PostgreSQL (meta DB)
Role: Stores platform metadata such as user information, site settings, and asset settings.
./shell.sh # 컨테이너 진입
# 컨테이너 내부에서
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node psql # PostgreSQL 셸 접속
psql=# SELECT 1;
psql=# SHOW max_connections;
psql=# SELECT count(*) FROM pg_stat_activity;
| Symptom | Cause | Solution |
|---|---|---|
| Connection refused | PostgreSQL component down | Run pd restart storage inside the container. From the host: ./restart.sh |
| Too many connections | Connection pool exceeded | Review the connection pool settings in properties. If temporary, restart storage |
| Authentication failed | Password mismatch | Check /etc/kopens/plantpulse-platform.env's PP_PG_PASSWORD against the application properties |
Path check — The secret sidecar's canonical file is a single
/etc/kopens/plantpulse-platform.env(permissions0600). An old installation may still have a file of the same name under/opt/kopens/, but it is not read, and the installation script restores the canonical file → Environment Variables Reference
Cassandra (time series DB)
Role: Stores large volumes of data such as sensor time series data and alarm history.
./shell.sh
# 컨테이너 내부에서
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status # 클러스터 상태
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node compactionstats # 컴팩션 진행 상태
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node cql # CQL 셸 접속
| Symptom | Cause | Solution |
|---|---|---|
| Connection timeout | Node down | Check node status with pd node status, then pd restart storage |
| WriteTimeout | Write delay (disk I/O saturation) | Check pd node compactionstats, run manual compaction with pd node compact |
| ReadTimeout | Read delay (large partition) | Check partition size with pd node table-histograms |
| Insufficient disk space | SSTable accumulation | Run pd node cleanup, then verify with df -h /data1 |
Valkey (Redis cache)
./shell.sh
# 컨테이너 내부에서
redis-cli -a "$PP_REDIS_PASSWORD" ping
redis-cli -a "$PP_REDIS_PASSWORD" INFO memory
Login / Console Access Issues
Symptom: Cannot access console from browser
# 1. 컨테이너 health 확인
./status.sh
# 2. 외부 노출 IP 설정 확인
grep DOCKER_PP_EXTERNAL_IP env.sh
# 3. 호스트 방화벽 확인
sudo firewall-cmd --list-ports # RHEL/Rocky/Oracle
sudo ufw status # Ubuntu
# 4. 포트 점유 확인 — 프록시가 80/443 을, 데이터레이크가 7443 을 엽니다
ss -tlnp | grep -E ':(80|443|7443)\s'
| Symptom | Cause | Solution |
|---|---|---|
| Page doesn't open | plantpulse-proxy is abnormal | Check proxy status with ./status.sh. The proxy is the sole entry point receiving 80/443 |
| Page doesn't open | Blocked by firewall | Request that 80, 443, 7443, 4950 be allowed on the company/cloud firewall |
| Login fails | Password mismatch | Check the default admin / admin123!. If changed, request a reset from the administrator |
| 403 Forbidden | Insufficient user permission | Ask the administrator to check the role |
| Session expired | Automatic logout after 30 minutes of inactivity | Log in again |
Data Collection Issues
Data collection path: OPC server → message broker (Kafka/MQTT) → engine pipeline → Cassandra. If any point in this path is blocked, data will not come in.
Symptom: Data not being collected
| Check item | How to check |
|---|---|
| OPC connection status | Check CONNECTED in Web Console > Connection Management > Status |
| Engine status | Check RUNNING in Console > Monitoring > System Status |
| Pipeline | If MPS (messages per second) is 0, reception has stopped |
| Message broker | Enter ./shell.sh and check the Kafka topic with /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node topic |
| Network | Ping / telnet from OPC server → platform host IP |
Symptom: Data delay
| Cause | Solution |
|---|---|
| Pipeline queue buildup | Raise engine.pipeline.threads in properties |
| Cassandra write delay | Check pd node compactionstats, monitor disk I/O |
| Kafka lag | Check consumer lag with pd node topic |
| Network latency | Measure RTT between OPC server ↔ platform host |
Performance Issues
Symptom: Console / API response is slow
# 호스트에서 컨테이너 자원 사용량
docker stats --no-stream
# 앱 컨테이너의 JVM 메모리 (그 앱이 도는 컨테이너 안에서)
./shell.sh plantpulse-server-web
jmap -heap $(pgrep -f plantpulse-server)
Since the six apps each run in their own container, you won't find app processes inside the data lake. Identify the target container with ./status.sh, then enter it with ./shell.sh <컨테이너>.
| Cause | Solution |
|---|---|
| Container out of memory | Raise the limit for the relevant container, then ./restart.sh — data lake is DOCKER_DATALAKE_MEMORY, apps are DOCKER_SERVER_MEMORY, etc. (Environment Variables) |
| JVM out of memory | Adjust heap size in setenv inside the container (see Performance Tuning for details) |
| Frequent GC | Analyze GC logs, tune G1GC options |
| DB slow query | Check PostgreSQL slow query logs |
| Host CPU saturation | Check top / htop, then consider raising DOCKER_PP_CPUS |
Symptom: OutOfMemoryError
# 컨테이너 내부에서 heap dump 활성화
./shell.sh
# setenv 또는 JAVA_TOOL_OPTIONS 에 -XX:+HeapDumpOnOutOfMemoryError 추가
# 생성된 hprof 를 호스트로 복사
docker cp plantpulse-datalake:/path/to/heap.hprof /tmp/
Analyze with Eclipse MAT / VisualVM.
Alarm Issues
| Symptom | Cause | Solution |
|---|---|---|
| Alarm not triggering | Alarm settings not deployed | Click "Deploy" on the alarm settings screen |
| Duplicate alarms | Duplicate check disabled | Enable duplicate check in alarm settings |
| Email notification not sent | SMTP configuration error | Check mail.properties (inside container: /opt/kopens/plantpulse-platform/plantpulse-server/config/) |
| No notification sound | Browser autoplay policy | Allow site autoplay in browser settings |
UI Issues
| Symptom | Solution |
|---|---|
| Screen rendering broken | Clear browser cache (Ctrl+Shift+Delete) |
| Chart not displayed | Check JS errors in browser DevTools (F12) > Console |
| Real-time updates cut off | Check SSE (HTTP streaming) buffering/timeout settings on proxy/firewall |
| Dashboard fails to load | Check whether connected tags / data sources exist |
| Korean text broken | Check env.sh, PP_LANG=ko, PP_TZ=Asia/Seoul in ./restart.sh, then ./restart.sh |
Disk / Volume Issues
Symptom: Insufficient disk space
# 호스트 디스크 사용량
df -h
df -h /data1 # 데이터 디스크
# Docker 사용량 (이미지 / 볼륨 / 빌드 캐시)
docker system df
# 컨테이너 내부 사용량
./shell.sh
df -h
du -sh /opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra/data
| Cause | Solution |
|---|---|
| Accumulated old backups | Clean up old tar.gz files under /data1/pp-backup/docker-volume |
| Unused Docker images | Clean up with docker system prune (images/networks/cache) |
| Cassandra SSTable accumulation | Inside container: pd node cleanup, pd node compact |
| Bloated log directory | Clean up /opt/kopens/plantpulse-platform-docker/logs |
Caution:
docker volume prunedeletes all unused volumes. Do not leave a container stopped, as this could accidentally delete thepp-*volume.
Symptom: Volume data recovery needed
Refer to the recovery procedure on the Operations Management - Backup and Recovery page.
Update / Rollback Issues
Symptom: Container doesn't work properly after update
./update.sh automatically rolls back to the previous image if health verification fails. For manual rollback:
# 1. 이전 버전 태그를 env.sh 에 지정
vi env.sh
# PP_IMAGE_TAG="2026.04" ← 이전 안정 버전
# 2. 업데이트 재실행
./update.sh
Symptom: NOT FOUND CONTAINER during update
Initial installation (./install.sh) has not been completed. Please perform the installation first.
Network / Cluster Issues
Symptom: Worker fails to join the master
# 1. 워커 컨테이너 진입 (워커는 기본 스택의 서비스가 아니라 shell.sh 로는 잡히지 않습니다)
docker exec -ti plantpulse-worker-1 /bin/bash
# 워커 내부에서 마스터 IP 로 연결 테스트
ping ${PP_MASTER_IP}
# 2. 마스터에서 링 확인 — 이것이 조인의 «유일한» 증거입니다
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status
# 3. JGroups / Cassandra 포트 (7000, 7001, 7800, 7801, 9042) 방화벽 허용 확인
A worker that failed to join reports as normal, exactly like one that succeeded — because the container's own check only looks at "can it reach the master?" In a measurement taken on 2026-08-31, a worker whose Cassandra was OOMKilled kept reporting health: starting even while the ring stayed at 1 node.
Always judge by the ring list from pd node status. For adding workers, bin/worker-add.sh performs this check for you → Cluster Installation
Symptom: MQTT / Kafka external client connection failure
Check that 1883/1884 (MQTT) and 9092/9093/9094 (Kafka) are allowed on both the host firewall and the company/cloud firewall. For a detailed port list, see Port Configuration Information.
plantpulse-proxyreceives MQTT. Equipment only needs to know this host, and equipment settings don't need to be touched even if the broker moves or is renamed. 1884 is TLS passthrough, so the broker terminates TLS.- Kafka does not pass through the proxy. The client reconnects to the
advertised.listenersaddress after bootstrapping — if only bootstrap succeeds and everything after fails silently, suspect this address first.
Emergency Response
When a container is unresponsive
cd /opt/kopens/plantpulse-platform-docker/bin
# 1. 상태 확인
docker ps -a
./status.sh
# 2. 로그에서 마지막 에러 확인
./logs.sh -n 200
# 3. 안전 재시작
./restart.sh
# 4. 위 단계로 회복 안 될 경우 진단 tarball 생성
./doctor.sh
# 생성된 tarball 을 webmaster@kopens.com 으로 전달
If data corruption is suspected
# 1. 즉시 정지 (추가 손상 방지)
./down.sh
# 2. 최신 백업 확인
ls -lh /data1/pp-backup/docker-volume/
# 3. 진단 tarball 생성 (절대 데이터를 임의로 수정하지 마세요)
./doctor.sh
# 4. 기술 지원팀 연락
Prohibited actions in case of data corruption: Do not directly perform
pd node repair,pd node cleanup, SSTable deletion, etc. Incorrect recovery operations can expand the damage. Be sure to consult with technical support before proceeding.
Information Needed When Requesting Support
If the above methods don't resolve the issue, sending the following information along with your request enables faster analysis.
| Item | How to collect |
|---|---|
| Diagnostic tarball | File generated after running ./doctor.sh |
| Container logs | ./logs.sh -n 500 > /tmp/container.log 2>&1 (all eight containers) |
| Per-module logs | Result of ./tools/copy-log-to-local.sh (/tmp/plantpulse-log/) |
| Image version | Output of ./stack-version.sh |
| Environment variables | env.sh (passwords masked) |
| System information | OS, CPU, memory, disk (uname -a, free -h, df -h) |
| Error message | Exact error message / browser console (F12) capture |
| Reproduction steps | Sequence of actions performed right before the issue occurred |
Technical Support: webmaster@kopens.com
Related Documents
- FAQ — Frequently asked questions
- Operations Management — Daily operations commands
- Startup Guide — Start/stop/restart procedures
- Backup and Recovery — Detailed backup procedures
- Performance Tuning — JVM / DB tuning
- Port and Service Management — Port conflict diagnosis