Skip to main content

Container Mode Operation

Starting from the 2026.05 release, PlantPulse Edge is deployed as a single Docker container. This page is a comprehensive guide for the daily operation and troubleshooting of the container mode.

native mode

For boxes using the existing native deployment (installed directly on the system), please continue to use the native pages such as 시작 (start.sh), 중지 (stop.sh), and 재시작 (restart.sh) in the left menu. This page is exclusively for container deployments (systemctl status plantpulse-edge.service is active).

Container vs native — Where is it running?​

# 컨테이너 모드면 active
systemctl is-active plantpulse-edge.service

# 또는 직접 확인
curl -ks https://127.0.0.1/api/v1/system/version | grep container_mode

container_mode=true → Container mode. If container_mode=false or the endpoint does not respond, it is native.

One-line status check​

sudo bash /opt/kopens/install/bin/status.sh

Output items:

  • Container: name / image / image_tag / state / health / started time
  • Resources: CPU usage / MEM usage / PID count
  • Listening ports: 9 ports (80, 443, 1883, 1884, 6379, 9042, 1880, 12000, 12443). 7799 (Tomcat JMX) is not listed as it is exclusive to 127.0.0.1.
  • App.properties core keys (edge.id / site_id / dev.mode / mqtt.enable / sparkplug.enable)
  • API: /api/v1/system/version + /api/v1/system/health response + HTTP code
  • Upgrade status: /etc/kopens/upgrade.status content (idle/trial/committed/...)

Daily operation commands​

TaskCommand
Check statusbash /opt/kopens/install/bin/status.sh
Health check (exit code based)bash /opt/kopens/install/bin/health.sh
View logsbash /opt/kopens/install/bin/logs.sh tomcat (or cassandra/mqtt/redis/node-red/api/catalina)
Follow logsbash /opt/kopens/install/bin/logs.sh -f tomcat
Container internal shellbash /opt/kopens/install/bin/shell.sh
Change configurationbash /opt/kopens/install/bin/config.sh --set <key> <value>
Restartsudo systemctl restart plantpulse-edge.service
Backupsudo bash /opt/kopens/install/bin/backup.sh
Recoverysudo bash /opt/kopens/install/bin/restore.sh <archive>
Diagnosis collection (escalation)sudo bash /opt/kopens/install/bin/doctor.sh
OTA upgradesudo bash /opt/kopens/install/upgrade.sh

Health check API​

/api/v1/system/version — No authentication required​

{
"data": {
"product_name": "PlantPulse Edge",
"version": "2026",
"build_date": "20260523",
"image_tag": "2026-20260523",
"container_mode": true
},
"meta": {
"timestamp": 1778925572946,
"request_id": "..."
}
}

Primary use: OTA upgrade verification, fleet inventory for monitoring tools.

/api/v1/system/health — No authentication required, HTTP 503 if any DOWN​

{
"data": {
"status": "UP",
"uptime_ms": 1720008,
"components": {
"cassandra": "UP",
"redis": "UP",
"mqtt": "UP",
"node_red": "UP",
"opc_ua": "UP"
}
}
}

If any component is DOWN, returns status=DEGRADED + HTTP 503. For OTA upgrade.sh, the trial run is determined via a separate judgment address /api/health?verdict=upgrade&expect_build=<빌드일> (default 300 seconds).

Data / Configuration location​

/data1/ # 컨테이너 ↔ host bind mount, 컨테이너 교체에도 보존
├── pp-data/
│ ├── cassandra/{data, hints} # SSTables, hints
│ ├── redis/ # AOF / RDB
│ ├── hivemq/ # MQTT persistence
│ └── node-userdir/ # Node-RED flows + node_modules
├── pp-temp/cassandra/commitlog # 휘발성 commit log
└── pp-backups/ # backup.sh 산출물 + OTA pre-snapshot

/etc/kopens/ # 설정 + signal files (read-write mount)
├── app.properties # 메인 설정 (165줄, 16개 섹션)
├── credentials.txt # 박스별 비번 (chmod 0600, 설치 시 1회 출력)
├── version.env # KOPENS_VERSION=<tag>
├── upgrade.status / upgrade.request # OTA 시그널
└── host-action.status / .request # restart/reboot/clean signal

/var/security/plantpulse/edge/ # SSL keystore (read-only mount, 100년 self-signed)

OTA upgrade​

Automatic (Latest from product.kopens.io)​

sudo bash /opt/kopens/install/upgrade.sh

By specific tag​

sudo bash /opt/kopens/install/upgrade.sh --to 2026.11-20261103-1006

Only immutable tags (YYYY.MM-YYYYMMDD-HHMM) are accepted.

Rollback of upgrade in progress​

sudo bash /opt/kopens/install/upgrade.sh --rollback

Works only in trial · rollback_failed states. It does not allow downgrading from a committed build to an older build.

Check for existence of new build only​

sudo bash /opt/kopens/install/upgrade.sh --check

Flow​

The sequence is identical to the «Execution Order» in Upgrade. Pre-inspection → Download → Signature verification → Snapshot → Transition → Trial run → Commit or automatic rollback.

States: cat /etc/kopens/upgrade.status — idle · downloading · verified · snapshot · switching · trial · committed · rolling_back · rolled_back · rollback_failed.

UI / API trigger (inside container)​

POST /api/v1/system/upgrade uses /etc/kopens/upgrade.request.

Host kopens-upgrade.path (inotify) detects → upgrade.sh --from-trigger executes.

Passwords (at mass production shipment)​

From iter 9 (2026.05) onwards, random passwords are automatically generated for each box during the first install.sh execution.

  • Location: /etc/kopens/credentials.txt (chmod 0600 root)
  • Content: admin / mqtt / opcua / API key / keystore passwords
  • Shipment procedure: Print/save → include when sealing the box → can be re-verified using cat (root only)

Changing during operation:

config.sh --set edge.admin_password "NewStrongPass!"
config.sh --restart

Since HiveMQ auth.properties automatically syncs with mqtt.* in /etc/kopens/app.properties at every boot via the entrypoint, only app.properties needs to be changed.

Resource limits (cgroup)​

systemd unit defaults:

keyvalue
MemoryMax12G
MemoryHigh11G
CPUQuota600% (6 cores)
TasksMax8192

Override for 8GB boxes (drop-in)​

sudo mkdir -p /etc/systemd/system/plantpulse-edge.service.d
sudo tee /etc/systemd/system/plantpulse-edge.service.d/override.conf <<'EOF'
[Service]
Environment=HIVEMQ_HEAP=1g
Environment=CASSANDRA_HEAP=1g
Environment=TOMCAT_HEAP=1g
MemoryMax=6G
MemoryHigh=5G
EOF
sudo systemctl daemon-reload
sudo systemctl restart plantpulse-edge.service

Component heap defaults​

  • HiveMQ : -Xms2g -Xmx2g (override via env HIVEMQ_HEAP — 2026-07 heap standard 2g)
  • Cassandra : auto-calc based on host /proc/meminfo (1/4 of total) — 16G host → ~4G (env CASSANDRA_HEAP)
  • Tomcat : -Xms2g -Xmx2g (env TOMCAT_HEAP)
  • Redis / Node-RED : Default

Logs​

logrotate (cronie) inside the container automatically handles daily / size>100M triggers / 14-day gzip retention / copytruncate (without app restart).

ComponentPath (inside container)tool
Tomcat app$PE_HOME/server/log/system.loglogs.sh tomcat
Tomcat stdout$PE_HOME/server/logs/catalina.outlogs.sh catalina
Cassandra$PE_HOME/db/logs/system.loglogs.sh cassandra
HiveMQ$PE_HOME/mqtt/logs/hivemq.loglogs.sh mqtt
Redis$PE_HOME/cache/log/redis.loglogs.sh redis
Node-RED$PE_HOME/node/log/node-red.loglogs.sh node-red
API audit$PE_HOME/server/log/api.loglogs.sh api
hostjournalctl -u plantpulse-edge.servicejournalctl

Troubleshooting (Brief)​

For installation scenarios (mass production line · single box site · CI), refer to Installation.

SymptomQuick Fix
Some /health components DOWNTrace cause with logs.sh <component>. For mqtt, verify password match between auth.properties / app.properties
Container restart loopCheck journalctl -u plantpulse-edge -n 100 + port occupancy (ss -tlnp | grep :80)
/ui/apps docker card is emptyMissing docker.sock mount — check -v /var/run/docker.sock in systemd unit
PLC blinkingCheck NET_RAW cap / PLC port (MELSEC 5001, LS 2004, Modbus 502, OPC UA 49320)

If not recovered within 30 minutes → escalation​

sudo bash /opt/kopens/install/bin/backup.sh # 1. 악화 전 스냅샷
sudo bash /opt/kopens/install/bin/doctor.sh # 2. 진단 tarball (≈200KB)
# 3. /tmp/pe-doctor-*.tar.zst + .sha256 을 support@kopens.io 또는 https://support.kopens.io 업로드

pe-doctor tarball contents: api / docker / systemd / 7-component logs / config (passwords redacted) / host metrics.

  • Installation: 설치 > 한눈에 보기
  • Full REST API: 고급 / 통합 파트너용 > REST API
  • Host OS / sysctl / nmcli: Box /opt/kopens/install/install.sh
  • Installation Scenarios: Installation