Docker(容器)安装详解 — plantpulse-edge.service
自 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。日常运维请参阅
容器模式运维指南。
容器为 plantpulse-edge.service,native 为 plantpulse.service。systemd unit 中虽已设置
Conflicts=plantpulse.service,但强行同时启动两个服务会导致端口/数据冲突。
1. 镜像坐标
| 项目 | 值 |
|---|---|
| Registry | docker.kopens.io/pe (anonymous pull) |
| 镜像名 | plantpulse-edge |
| 完整坐标 | docker.kopens.io/pe/plantpulse-edge:<tag> |
| Tag 格式 | <VERSION>-<BUILD_DATE> 例:2026-20260524(或 latest) |
| 下载服务器 | 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 一行命令
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) - 应用
PROFILEpreset(若存在,见第 3 章) - 交互式 prompt — Edge ID(基于 MAC 自动建议)/ Site ID(默认
SITE_00001)/ Mode(1=EDGE默认 /2=STANDALONE)/ 若为 EDGE 模式则需平台服务器 + API key - 执行
install.sh主体的 9 个步骤
2.2 install.sh 九个步骤
| # | 步骤 |
|---|---|
| 1 | OS 检测 (Rocky/Alma/RHEL/Ubuntu/Debian) |
| 2 | 安装 Docker(dnf 或 apt) |
| 3 | 创建 /data1、/etc/kopens、/var/log/kopens 目录 |
| 4 | sysctl + firewalld 端口 + chrony + hostname + nmcli static 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 签名校验 — 默认 soft-fail) |
| 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 preset
通过 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,
边缘自诊断 OPC 会因 FK 冲突而失败,因此应直接沿用已注册的 EDGE/site。
若与 dev 同时连接平台会被识别为同一 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(zombie reap + signal forward) |
--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(存在时 override — 以最新值优先):
| 文件 | 键 | 生成者 |
|---|---|---|
/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 缩减 override(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 进行 seed。运维人员编辑后 → 通过config.sh --restart生效。 - log4j2.xml:entrypoint 每次启动时从 webapp default 复制到
conf/log4j2.xml(代码产出物 — 无需重建镜像即可修改日志级别后 restart)。 - HiveMQ auth.properties:entrypoint 每次启动时与
app.properties的mqtt.server.*自动 sync — 只需修改app.properties即可。 - TLS 密码:entrypoint 从
cert.env解析CERT_PASS,并统一 patch Tomcatserver.xml/ HiveMQ config / OPC-UA keystore 密码。
env→配置镜像映射详情见 env 环境配置,各键含义见 app.properties 指南。
6. OTA 升级 / 回滚
版本由 /etc/kopens/version.env 中的 PE_VERSION 一行固定 — OTA 只修改该文件并 restart。
# 최신으로 업그레이드 (pre-snapshot → pull → restart → 90초 health probe → 실패 시 auto-rollback)
sudo bash /opt/kopens/install/upgrade.sh
# 특정 tag 로
sudo bash /opt/kopens/install/upgrade.sh --to 2026-20260601
# 직전 tag 로 rollback
sudo bash /opt/kopens/install/upgrade.sh --rollback
# 새 빌드 존재만 확인
sudo bash /opt/kopens/install/upgrade.sh --check
手动回滚:
echo 'PE_VERSION=2026-20260524' > /etc/kopens/version.env
sudo systemctl restart plantpulse-edge.service
状态:cat /etc/kopens/upgrade.status → idle | running | success | rolling-back | rolled-back | error。
流程详情见 容器模式 §OTA。
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>
部署仅可经由流水线 — 镜像 (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) — 现场单台安装步骤摘要 - env 环境配置 —
PROFILE/PP_LANG/CERT_PASS/-Dpe.conf.dir - 原生安装 — 不使用容器的直接安装 (dev/legacy)
- 容器模式运维指南 — pe-* 工具 / 日志 / 故障处理
- 离线 / 隔离网络安装 / 量产产线 (
factory.sh) - 生产验收标准