跳到主要内容

Docker 安装

从 2026.05 起,PlantPulse Edge 的量产/现场标准发布采用单一 Docker 容器镜像。 7 个组件(Tomcat / Cassandra / Redis / HiveMQ / TSE / Dashboard / Node-RED)被包含在一个镜像中,由 install.sh 处理从 OS 依赖到 systemd 注册的所有流程,随后由 plantpulse-edge.service 管理容器。

快速安装 vs 本页

现场快速部署单台设备的流程摘要请参阅 快速安装 (install.sh)。 本页是深入探讨该安装过程内部运行机制的参考指南,涵盖镜像坐标、docker run 标志、bind mount、EnvironmentFile 及 OTA 等内容。日常运维请参阅 容器模式运维。

禁止与 native 同时使用

1. 镜像坐标​

项目值
Registrydocker.kopens.io/pe (anonymous pull)
镜像名称plantpulse-edge
完整坐标docker.kopens.io/pe/plantpulse-edge:<tag>
Tag 格式YYYY.MM-YYYYMMDD-HHMM 例如:2026.11-20261103-1006 (安装时 latest 亦可,OTA 仅限不可变标签)
下载服务器https://product.kopens.io/plantpulse-edge/ (LAN alias)

镜像内固定路径:KOPENS_HOME=/opt/kopens, PE_HOME=/opt/kopens/plantpulse-edge, PE_DATA_DIR=/data1, JAVA_HOME=/usr/lib/jvm/java-21-openjdk。


2. 安装流程 — bootstrap.sh → install.sh​

2.1 一键安装 (One-liner)​

curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh | sudo bash

install.sh 与 bootstrap.sh 相同。该脚本执行以下操作:

  1. 将 repo tarball(plantpulse-edge-docker.tar.gz) 解压至 /opt/kopens/plantpulse-edge-docker/ (失败时执行 git clone 回退)
  2. 应用 PROFILE 预设(若存在,详见第 3 章)
  3. 执行 install.sh 主体 9 个步骤
⌨️ 安装过程中«询问的项目» — 包含留空则重新询问的场景。此界面并非实际运行安装时的录屏(否则会导致真实配置被修改),而是直接运行安装程序所使用的提示符库进行重现。如重复询问等«行为»为真实,项目列表由 CI 与安装程序声明进行双向比对以确保一致性
根据模式,«询问内容»有所不同 — 默认为 EDGE

在终端直接执行时会进行询问(默认行为)。方括号内为默认值,按 Enter 接受。

  • EDGE(默认) — 必须询问平台地址和 API 密钥,若留空则重新询问。
  • STANDALONE — 完全不询问上述两项。
  • Edge id 默认值随设备而异(由 NET1 MAC 衍生出 EDGE_3F8A21 格式)。 如需指定现场编号,请在此输入。
通过 curl | bash 无法进行询问 — 请通过环境变量传值

通过管道执行时由于未挂接终端,无法进行询问。此时脚本将提示「无法询问」,随后基于环境变量和默认值继续执行(不会静默跳过)。

curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh | \
sudo EDGE_ID=EDGE_00303 DEV_MODE=EDGE \
SERVER_HOST=<플랫폼IP> SERVER_API_KEY=<token> bash

如需触发值询问,请下载脚本后直接执行。在自动化(CI·无人值守安装)场景中,建议通过 INTERACTIVE=0 明确关闭询问功能。

运维人员仅需操作 env.sh 即可

将其写入与脚本同目录的 env.sh 中,安装程序将自动读取。重新安装时也会沿用相同的值。

2.1a 安装过程中«验证»平台密钥​

若为 DEV_MODE=EDGE,在写入配置前会实际询问平台。此前版本仅检查值是否为空即结束安装,导致启动后所有连接均因 401 错误而中断。

场景安装程序行为
无法触达平台仅警告 — 平台尚未上线或防火墙尚未配置
服务器 5xx仅警告 — 无法做出判定,非密钥问题
401 · 403🔴 中断 — 密钥被拒绝。此处可拦截输入错误
400🔴 中断 — 安装程序侧问题,请反馈

如需在平台之前安装,可通过 SKIP_PLATFORM_VERIFY=1 关闭验证。

2.1b 使用指南以 --help 为准​

sudo bash install.sh --help # root 없이도 읽힙니다
⌨️ `--help` 全文 — 由于输出在 0.04 秒内一次性打印,故以«静止画面»呈现。此录屏源自与安装程序«相同的发行版执行环境」,即当前下载脚本的实际界面

将与横幅一起显示 USAGE · MODE decides what else is required · IDENTITY · PLATFORM · IMAGE · NETWORK · SKIP FLAGS · PROFILE · AFTER INSTALL 章节。本手册未完整摘录全文,是因为摘录的副本会随时间失效。 实际上曾出现过本仓库的页眉与代码默认值不一致的情况。

2.2 install.sh 9 个步骤​

#步骤
1OS 检测 (Rocky/Alma/RHEL/Ubuntu/Debian)
2Docker 安装 (dnf 或 apt)
3创建 /data1, /etc/kopens, /var/log/kopens 目录
4sysctl + firewalld 端口 + chrony + hostname + nmcli 静态 IP
5生成 /etc/kopens/app.properties (EDGE_ID / SITE_ID / 每台设备随机凭证)
6systemd unit 安装 — plantpulse-edge.service + OTA kopens-upgrade.path/.service
7docker pull (cosign 签名验证 — 安装时仅警告,升级时验证失败则中断)
8systemctl enable --now plantpulse-edge.service
9注册 cron 每周清理 (weekly cleanup)

首次安装时,admin / MQTT / OPC-UA / API key / keystore 密码将按设备随机生成,并一次性保存至 /etc/kopens/credentials.txt (chmod 0600 root)。


3. PROFILE 预设​

通过 PROFILE env 一次性应用各站点类型的默认值。

PROFILE应用默认值
productionDEV_MODE=EDGE (需明确平台 SERVER_HOST/SERVER_API_KEY)
stagingDEV_MODE=EDGE, EDGE_ID=EDGE_00303, SITE_ID=SITE_00001, SERVER_HOST=192.168.0.235, SKIP_COSIGN_VERIFY=1
standaloneDEV_MODE=STANDALONE, SKIP_COSIGN_VERIFY=1 (不连接平台)
airgapIMAGE_URL=tarball, SKIP_PULL=1, DEV_MODE=STANDALONE (隔离网络安装)
# 양산 (플랫폼 연결)
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh \
| sudo PROFILE=production EDGE_ID=EDGE_00303 \
SERVER_HOST=10.0.0.5 SERVER_API_KEY=<uuid> bash

# 단독 운영 (플랫폼 없이)
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh \
| sudo PROFILE=standalone EDGE_ID=EDGE_LOCAL_01 bash
staging = dev 克隆

staging 设备是 dev 的相同 EDGE_00303 / SITE_00001 克隆。唯一不同点是平台连接信息(SERVER_HOST=192.168.0.235 / API key)。如果使用未在平台注册的 site,Edge 自诊断 OPC 将因 FK 违例而失败,因此请直接使用已注册的 EDGE/site。 若 dev 与 staging 同时连接至平台,将被识别为同一 edge,因此验证时请避免重叠运行。

安装时常用的完整 env 列表请参阅 env 环境配置 §6。


4. systemd unit 解剖 — plantpulse-edge.service​

这是 install.sh 通过 /etc/systemd/system/plantpulse-edge.service 部署的实际容器启动定义。

4.1 docker run (ExecStart)​

/usr/bin/docker run --rm --name plantpulse-edge \
--network=host \
--init \
--stop-timeout=120 \
-v /data1:/data1:z \
-v /etc/kopens:/etc/kopens:z \
-v /etc/kopens/conf:/opt/kopens/plantpulse-edge/conf:z \
-v /var/security:/var/security:rw,z \
-v /etc/localtime:/etc/localtime:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-e PP_LANG=${PP_LANG} \
-e PP_TZ=${PP_TZ} \
-e CERT_PASS=${CERT_PASS} \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--cap-add=NET_RAW \
--cap-add=DAC_OVERRIDE \
--cap-add=CHOWN \
--cap-add=FOWNER \
--log-driver=journald \
--log-opt tag="plantpulse-edge" \
${KOPENS_IMAGE}:${PE_VERSION}
标志含义
--network=host自动暴露 9 个端口 + multicast / OPC-UA discovery 机制
--init由 tini 作为 PID 1 (僵尸进程回收 + 信号转发)
--stop-timeout=120为 Cassandra 确保优雅排空 (graceful drain) 时间
--cap-drop=ALL + 各项 --cap-add最小权限。NET_RAW 用于 PLC ping,NET_BIND_SERVICE 用于绑定 80/443

4.2 bind mount​

Host 路径容器路径模式用途
/data1/data1rw,z数据 (Cassandra/Redis/HiveMQ/Node-RED) — 容器更换后依然保留
/etc/kopens/etc/kopensrw,z配置 + 信号文件
/etc/kopens/conf/opt/kopens/plantpulse-edge/confrw,zapp.properties / log4j2.xml
/var/security/var/securityrw,zTLS keystore
/etc/localtime/etc/localtimero主机时区
/var/run/docker.sock/var/run/docker.sockrw/ui/apps Docker 应用管理

4.3 EnvironmentFile + 默认值​

unit 内置默认值(文件缺失时):

Environment=PE_VERSION=latest
Environment=KOPENS_IMAGE=docker.kopens.io/pe/plantpulse-edge
Environment=PP_LANG=en
Environment=PP_TZ=Asia/Seoul
Environment=CERT_PASS=kopens123!

EnvironmentFile (存在时覆盖 — 以最新值为准):

文件键生成者
/etc/kopens/version.envPE_VERSION=<tag>OTA upgrade.sh
/etc/kopens/i18n.envPP_LANG / PP_TZinstall.sh
/etc/kopens/cert.envCERT_PASSTLS 签发脚本

4.4 资源限制 / 重启策略​

MemoryMax=12G # 16GB 박스 기준 — 호스트 OOM 방지
MemoryHigh=11G
CPUQuota=600% # 6 cores
TasksMax=8192

Restart=on-failure
RestartSec=30s
TimeoutStartSec=300
TimeoutStopSec=180

针对 8GB 设备的 heap 缩减覆盖(drop-in)请参阅 容器模式 §资源限制。


5. 容器运行时配置读取路径​

在 WAR 模式(2026-06-13~)中,配置直接从主机的 /etc/kopens 读取 — 无需重新构建镜像。

/etc/kopens/app.properties ← 운영자가 편집하는 canonical
│ (entrypoint 가 symlink 생성)
▼
/etc/kopens/conf/app.properties ──bind──▶ /opt/kopens/plantpulse-edge/conf/app.properties
▲
Tomcat setenv.sh: -Dpe.conf.dir=/opt/kopens/plantpulse-edge/conf
  • app.properties: 主机 /etc/kopens/app.properties 为唯一事实来源 (source-of-truth)。若不存在,entrypoint 将以 image default 填充。运维人员编辑 → 通过 config.sh --restart 生效。
  • log4j2.xml: entrypoint 在每次启动时将 webapp default 复制到 conf/log4j2.xml (属于代码产出物 — 可在不重新构建镜像的情况下更改日志级别并 restart)。
  • HiveMQ auth.properties: entrypoint 在每次启动时与 app.properties 的 mqtt.server.* 自动同步 — 仅需修改 app.properties 即可。
  • TLS 密码: entrypoint 将 CERT_PASS 在 cert.env 中解析,并统一补丁 Tomcat server.xml / HiveMQ config / OPC-UA keystore 密码。

详细的 env → 配置镜像关系请参阅 环境变数设定,各键含义请参阅 app.properties 参考。


6. OTA 升级 / 回滚​

版本号固定在 /etc/kopens/version.env — OTA 将此文件更改为经验证的摘要 (digest) 并执行 restart。

# 자동 (META-INF/VERSION.JSON 이 가리키는 빌드)
sudo bash /opt/kopens/install/upgrade.sh

# 특정 불변 태그 (YYYY.MM-YYYYMMDD-HHMM). 움직이는 태그는 거부합니다
sudo bash /opt/kopens/install/upgrade.sh --to 2026.11-20261103-1006

# 진행 중인 현재 업그레이드만 롤백 (trial · rollback_failed 상태에서만)
sudo bash /opt/kopens/install/upgrade.sh --rollback

# 사전 점검만 (0 최신, 10 새 빌드 있음)
sudo bash /opt/kopens/install/upgrade.sh --check

状态:cat /etc/kopens/upgrade.status → idle · downloading · verified · snapshot · switching · trial · committed · rolling_back · rolled_back · rollback_failed。 详细流程请参阅 升级。


7. 调试用手动 docker run​

运维必须通过 systemd / install.sh,但隔离调试时可手动启动:

sudo docker run --rm --name pe-debug \
--network=host --init \
-v /data1:/data1:z \
-v /etc/kopens:/etc/kopens:z \
-v /etc/kopens/conf:/opt/kopens/plantpulse-edge/conf:z \
-v /var/security:/var/security:rw,z \
-e PP_LANG=en -e PP_TZ=Asia/Seoul -e CERT_PASS="$(. /etc/kopens/cert.env; echo $CERT_PASS)" \
docker.kopens.io/pe/plantpulse-edge:<tag>

发布仅限通过流水线(pipeline) — 镜像 (re)build / push / staging 重新发布请勿在本地执行,应通过 plantpulse-edge-docker 的发布链(edge:libs → edge:deploy-dev → edge:image → edge:staging → edge:version,通过流水线变量 RELEASE=1 触发)。上述命令仅限于隔离调试。


8. 安装后验证​

systemctl is-active plantpulse-edge.service
sudo bash /opt/kopens/install/bin/status.sh

# version: container_mode=true 여야 함
curl -ks https://127.0.0.1/api/v1/system/version | python3 -m json.tool
# health: HTTP 200 + components UP
curl -ks https://127.0.0.1/api/v1/system/health | python3 -m json.tool
界面URL
Web UIhttps://<gateway-ip>/ui/main
Node-REDhttps://<gateway-ip>/ui/flow/
Swagger UIhttps://<gateway-ip>/public/swagger-ui/index.html

按症状排除故障请参阅 安装问题解决,日常运维/故障请参阅 容器模式运维。


9. 相关文档​