Docker 安装
从 2026.05 起,PlantPulse Edge 的量产/现场标准发布采用单一 Docker 容器镜像。
7 个组件(Tomcat / Cassandra / Redis / HiveMQ / TSE / Dashboard / Node-RED)被包含在一个镜像中,由 install.sh 处理从 OS 依赖到 systemd 注册的所有流程,随后由 plantpulse-edge.service 管理容器。
现场快速部署单台设备的流程摘要请参阅 快速安装 (install.sh)。
本页是深入探讨该安装过程内部运行机制的参考指南,涵盖镜像坐标、docker run 标志、bind mount、EnvironmentFile 及 OTA 等内容。日常运维请参阅 容器模式运维。
1. 镜像坐标
| 项目 | 值 |
|---|---|
| Registry | docker.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 相同。该脚本执行以下操作:
- 将 repo tarball(
plantpulse-edge-docker.tar.gz) 解压至/opt/kopens/plantpulse-edge-docker/(失败时执行git clone回退) - 应用
PROFILE预设(若存在,详见第 3 章) - 执行
install.sh主体 9 个步骤
在终端直接执行时会进行询问(默认行为)。方括号内为默认值,按 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 없이도 읽힙니다
将与横幅一起显示 USAGE · MODE decides what else is required · IDENTITY · PLATFORM · IMAGE · NETWORK · SKIP FLAGS · PROFILE · AFTER INSTALL 章节。本手册未完整摘录全文,是因为摘录的副本会随时间失效。 实际上曾出现过本仓库的页眉与代码默认值不一致的情况。
2.2 install.sh 9 个步骤
| # | 步骤 |
|---|---|
| 1 | OS 检测 (Rocky/Alma/RHEL/Ubuntu/Debian) |
| 2 | Docker 安装 (dnf 或 apt) |
| 3 | 创建 /data1, /etc/kopens, /var/log/kopens 目录 |
| 4 | sysctl + firewalld 端口 + chrony + hostname + nmcli 静态 IP |
| 5 | 生成 /etc/kopens/app.properties (EDGE_ID / SITE_ID / 每台设备随机凭证) |
| 6 | systemd unit 安装 — plantpulse-edge.service + OTA kopens-upgrade.path/.service |
| 7 | docker pull (cosign 签名验证 — 安装时仅警告,升级时验证失败则中断) |
| 8 | systemctl 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 | 应用默认值 |
|---|---|
production | DEV_MODE=EDGE (需明确平台 SERVER_HOST/SERVER_API_KEY) |
staging | DEV_MODE=EDGE, EDGE_ID=EDGE_00303, SITE_ID=SITE_00001, SERVER_HOST=192.168.0.235, SKIP_COSIGN_VERIFY=1 |
standalone | DEV_MODE=STANDALONE, SKIP_COSIGN_VERIFY=1 (不连接平台) |
airgap | IMAGE_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 的相同 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 | /data1 | rw,z | 数据 (Cassandra/Redis/HiveMQ/Node-RED) — 容器更换后依然保留 |
/etc/kopens | /etc/kopens | rw,z | 配置 + 信号文件 |
/etc/kopens/conf | /opt/kopens/plantpulse-edge/conf | rw,z | app.properties / log4j2.xml |
/var/security | /var/security | rw,z | TLS keystore |
/etc/localtime | /etc/localtime | ro | 主机时区 |
/var/run/docker.sock | /var/run/docker.sock | rw | /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.env | PE_VERSION=<tag> | OTA upgrade.sh |
/etc/kopens/i18n.env | PP_LANG / PP_TZ | install.sh |
/etc/kopens/cert.env | CERT_PASS | TLS 签发脚本 |
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中解析,并统一补丁 Tomcatserver.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 UI | https://<gateway-ip>/ui/main |
| Node-RED | https://<gateway-ip>/ui/flow/ |
| Swagger UI | https://<gateway-ip>/public/swagger-ui/index.html |
按症状排除故障请参阅 安装问题解决,日常运维/故障请参阅 容器模式运维。
9. 相关文档
- 快速安装 (
install.sh) — 现场单台安装流程摘要 - 环境变数设定 —
PROFILE/PP_LANG/CERT_PASS/-Dpe.conf.dir - 容器模式运维 — pe-* 工具 / 日志 / 故障应对
- 隔离网络安装 / 量产线 (
factory.sh) - 量产验收标准