跳到主要内容

Docker 安装

概述

本页介绍如何以 Docker Compose 栈的形式手动(分步)安装 PlantPulse 平台,以及隔离网络(Airgap)安装方法。

在常规环境中,建议使用一行安装。一行安装会一次性处理从包下载、自动环境检测、安装到启动验证的全过程。仅在以下情况下才使用本页的手动步骤:

  • 需要逐步审查·批准各个安装阶段的情况(安全审计、变更管理流程等)
  • 需要将环境变量(bin/env.sh)设置为手工指定的值而非自动检测值的情况
  • 在隔离网络环境中安装 → 隔离网络(Airgap)安装

安装成型 — 九个容器

平台以一个 docker compose运行。源文件是 compose/docker-compose.yml,所有运维脚本也都通过此文件来管理容器。

容器层级角色
plantpulse-certs证书烘焙 TLS 材料,完成后退出的一次性任务。正常状态为 Exited (0)
plantpulse-datalake基础设施存储·消息·分析·CEP·SQL·监控
plantpulse-server-web应用Web 控制台
plantpulse-batch-web应用批处理
plantpulse-warehouse应用数据仓库
plantpulse-plugin-opcua-server应用OPC-UA 服务器插件 (11004 / 11005)
plantpulse-plugin-aasx-server应用AASX 服务器插件
plantpulse-ha应用冗余恢复守护进程 (10210)
plantpulse-proxy边缘用户唯一的入口 (80 / 443 / 1883 / 1884)
常驻容器为八个

plantpulse-certs 是生成证书后自行退出的一次性任务,因此 Exited (0) 是正常的。在 docker ps 中应显示其余八个容器为 (healthy) 状态才是正常的。不要误以为这个容器"已死" — status.shops-check.sh 仅通过此容器的退出代码来判定。

此外,compose 中还定义了用于镜像的 plantpulse-mirror-maker,但它被 mirror 配置文件束缚,默认不会启动

之前的单容器配置已不存在

在 2026-08-29 之前,可以选择所有组件在一个 plantpulse-platform 容器中运行的"整体式"配置。此配置已被弃用,相关的选择变量(PP_TOPOLOGY)和 compose 文件也已删除。现在没有选择bin/up.sh 启动上述栈。

旧运维手册中留下的 docker logs plantpulse-platform 这样的命令由于该容器不存在而无法工作。替代命令请见运维命令汇总

按应用划分容器的首要目的是 OOM 隔离。一个应用用尽内存也不会影响其他应用和基础设施,可以按应用单位重启·回滚。

前置准备

开始安装前,请确认以下事项。

项目要求
账户权限root(或 sudo 权限)。安装脚本会配置 OS 设置和 Docker 守护进程
操作系统RHEL/Rocky/Oracle Linux 8·9、Ubuntu 20.04+、Amazon Linux 2/2023
Docker需要 Compose v2docker compose — 无连字符形式)。如果没有 install.sh 会自动安装
数据磁盘建议在 /data1 路径挂载大容量磁盘 — Docker 数据(/data1/docker-data)和平台数据卷将使用此路径
仓库访问必须能通过 HTTPS 访问 docker.kopens.io(镜像仓库)和 product.kopens.io(安装包)。访问受限的环境请使用隔离网络安装
仓库凭据docker.kopens.io 登录凭据(由 KOPENS 运营团队发放)

磁盘路径指南:如果没有单独的数据磁盘,也可以在根磁盘上创建 /data1 目录,但在生产环境中建议将专用磁盘挂载到 /data1

手动安装步骤

第 1 步:下载安装包

从下载服务器获取安装包(tar.gz)并解压到标准路径。无需 Git 克隆或额外工具安装。

sudo -i

# 표준 설치 경로 생성 후 패키지 다운로드 + 압축 해제
mkdir -p /opt/kopens/plantpulse-platform-docker
curl -fsSL "https://product.kopens.io/plantpulse-platform/plantpulse-platform-docker.tar.gz" \
| tar -xz -C /opt/kopens/plantpulse-platform-docker --strip-components=1

cd /opt/kopens/plantpulse-platform-docker/bin
chmod +x *.sh tools/*.sh

包内实际使用的位置有两处。

位置内容
bin/所有安装和运维脚本
compose/栈源文件 docker-compose.yml 及集群工作节点覆盖文件

第 2 步:前置检查 (preflight)

preflight.sh不会对系统进行任何修改,仅检查是否可以安装。

./preflight.sh

检查项目:

  • Docker 安装/守护进程运行情况(未安装也可以 — install.sh 会安装)
  • Docker data-root 上层路径(/data1)是否存在
  • 秘密 sidecar(/etc/kopens/plantpulse-platform.env)是否存在
  • 主要运维端口(80、443、7443、4949、4950)是否被占用

OK 说明继续下一步。若有 ERROR 请参考故障排除。(WARN 仅供参考,不会阻止安装。)

第 3 步:环境变量审查 (env.sh)

bin/env.sh主机端配置的源文件。容器实际看到的值由 compose/docker-compose.yml 确定 — 详细关系请参考环境变量参考

vi env.sh
资源值大多是"计算"得出的 — 很少需要修改

env.sh 通过查看主机自动配置 CPU·内存·磁盘。不是固定的默认值,所以即使不修改,小主机上也会使用较小的值。按主机指定的值总是优先

变量如何确定何时修改
DOCKER_PP_CPUSnproc(读取失败时 8想给容器分配更少核心时
DOCKER_PP_CLUSTER_CORESDOCKER_PP_CPUS - 2,最小 4·最大 30通常保持不变
DOCKER_PP_MEMORY主机 RAM 的90%,最小 8G想为 OS 保留更多空间时
DOCKER_DATALAKE_MEMORY80G。如果主机更小则为 RAM 的 90%调整数据湖上限
DOCKER_PP_DATA_DISK_NAME/ 支撑的实际磁盘自动反向推导(失败时 sda自动检测错误时
PP_LANGen韩国运营时设为 ko
PP_TZAsia/Seoul海外主机
DOCKER_PP_EXTERNAL_IP空值仅当 NAT 环境下需要告知外部公网 IP 时
不要在 DOCKER_PP_EXTERNAL_IP 中填入无效的 IP

该值会通过 PP_SERVICE_IP 进入 TLS 证书的 SAN 列表。如果混入任何格式不正确的 IP,openssl 将拒绝整个扩展文件,导致无法生成任何证书,栈将无法启动。如果不在 NAT 后面,请留空 — 这是默认值。

可以用以下命令查看当前服务器的值。

hostname -I | awk '{print $1}' # 서버 IP
free -g | awk '/^Mem:/{print $2"G"}' # 전체 메모리
nproc # CPU 코어 수
lsblk # 디스크 이름 (sda, sdb, nvme0n1 …)

在韩国运营的主机上,通常只需修改两行。

export PP_LANG=ko
export PP_TZ=Asia/Seoul
区域设置仅在启动时生效

PP_LANG / PP_TZ 在 JVM 启动时固定。若要在已运行的栈中修改,需要 ./restart.sh。另外,Cassandra 时序会以 KST epoch 加载,所以韩国运营时应保持 Asia/Seoul

第 4 步:执行安装 (install.sh)

sudo ./install.sh

install.sh 会自动执行整个安装前过程。

  1. OS 检测及系统配置 — 文件限制(limits)、内核参数(sysctl)、时间同步(chrony)、SELinux 改为 permissive、禁用 swap
  2. Docker Engine 安装 — 通过 OS 包管理器安装 + 将 data-root 配置为 /data1/docker-data(如果没有 Compose v2 会一起安装)
  3. 防火墙配置 — 开放公开端口(80/443/7443/4949/4950),内部端口仅允许专网段访问
  4. 生成服务凭据/etc/kopens/plantpulse-platform.env 秘密 sidecar 生成(权限 0600,重新运行也不会覆盖现有值)
  5. 仓库登录docker.kopens.io 凭据输入(已登录则自动跳过)
  6. 启动栈 — 创建网络/卷 → pull 镜像 → 种子配置模板 → docker compose up -d

安装时的一次性选项(仅在需要时通过环境变量指定):

选项效果
SKIP_OS=1跳过 OS 配置·Docker 安装(Docker 已安装并运行中)
SKIP_LOGIN=1跳过仓库登录(已登录或镜像在本地)
SKIP_FW=1跳过防火墙配置(防火墙单独管理)
DOCKER_DATA_DIR=<path>修改 Docker data-root(默认 /data1/docker-data
# 예: Docker가 이미 설치된 서버
SKIP_OS=1 sudo -E ./install.sh
更换凭据必须在安装前进行

秘密 sidecar(/etc/kopens/plantpulse-platform.env)是 export VAR=값 形式的无条件替换,会覆盖 shell export。安装后在该节点上运行 PP_PG_PASSWORD=... ./up.sh 会被无声忽略。交付时的更换应在安装前通过 export PP_*_PASSWORD=... 进行,安装后请使用密码轮换中的 passwd.sh

第 5 步:启动和启动验证

install.sh 会启动栈并返回。需要单独检查启动是否完成

./up.sh

up.sh 是幂等的,即使已启动也是安全的,会一直等待直到准备就绪。退出代码 0 不是"命令成功",而是**"现在可以使用了"**的意思。

环境变量默认值含义
PP_READY_TIMEOUT900等待准备就绪的超时时间(秒)
PP_READY_INTERVAL15检查间隔(秒)
PP_WAIT=0不等待。此时 0 不表示准备完成
最初的干净安装需要 15~18 分钟

进程启动本身需要 35 分钟(JVM 预热),但**整个组件稳定需要 1518 分钟**。Cassandra 模式迁移和稳定化最慢。重启则快得多,因为模式已存在。

实测基准(2026-08-31、32 vCPU / 128GiB):数据湖 217 秒、Web 服务器 316 秒。

也可以单独运行准备判定。

./stack-verify-boot.sh

此脚本检查的是整个栈而非单个容器 — 检查一次性任务是否正常退出、数据湖和应用是否为 running·healthy、代理是否服务 443 等。

第 6 步:状态和运维检查

./status.sh # 0 = 정상 / 2 = 비정상
./ops-check.sh

status.sh 汇总服务列表·容器状态·健康状态·卷。退出代码遵循协议 — 可以直接在自动化中使用。

判定何为异常
无法读取服务列表compose 解析失败或无法访问 docker
compose 声明的服务中缺少容器未启动
常驻容器状态不是 running不包括一次性任务(plantpulse-certs)
常驻容器的健康状态不是 unhealthystarting / none 保留判定
健康检查 API 不返回 OK数据湖内部探测

卷和 conf 仅报告但不计入退出代码 — 两节点分离安装(PP_TIER=APP)中某些缺失是正常的。

ops-check.sh 除此之外还会扫描最近的致命日志(OOM、FATAL、SSL 错误等)。

健康检查

监控 API 由 plantpulse-datalake 容器提供。根据查询的位置,命令不同

# 컨테이너 안에서 — 어떤 구성에서도 동작하는 방법
docker exec plantpulse-datalake curl -kfsS https://127.0.0.1:4950/api/health | jq

# 호스트/외부에서 — 4950 이 publish 되어 있습니다
curl -kfsS https://<server-ip>:4950/api/health | jq

"status"OKWARN 时为正常范围,为 FAIL 时为故障。

其他端口无法查看健康状态

控制台和健康检查 API 在两个端口上都提供服务4950(HTTPS)和 4949(纯文本 HTTP)。控制台和 API 相同,仅协议不同。4949 不再重定向到 4950。

4949 是纯文本的 — 登录密码和会话 cookie 以明文形式传输。在不信任的网络中请使用 4950。4949 是为那些自签证书警告实际上会阻止运维人员的主机准备的选择。

安装成果

网络和卷

资源名称用途
网络pp-net平台专用 Docker 网络(默认 10.99.0.0/24,网关 10.99.0.1
pp-data数据永久存储(Cassandra、PostgreSQL、Kafka 等)
pp-temp临时数据(Spark、Hive 工作空间)
pp-backup备份存储
pp-securityTLS 证书·密钥库。由 plantpulse-certs 写入,其余以只读方式访问
pp-proxy-certs代理在 443 上写入的证书

卷在容器停止或删除后始终保留,因此在更新·重新安装时数据也会保持。

主机目录

路径用途
/opt/kopens/plantpulse-platform-docker安装·运维脚本和 compose 源文件
/etc/kopens/conf平台配置模板(主机绑定挂载)。首次运行时从镜像自动种子,之后由运维人员直接在主机编辑,重新安装也会保留
/etc/kopens/plantpulse-platform.env服务凭据秘密 sidecar(权限 0600)
/etc/kopens/platform.node.env节点身份(PP_TIER 等)。禁止在节点间复制
/etc/kopens/ca共享集群 CA(两节点分离安装中使用)

访问地址

用途地址
Web 控制台http://<server-ip>/ · https://<server-ip>/ — 由 plantpulse-proxy 接收
管理 UIhttps://<server-ip>:7443
监控 UI · 健康检查https://<server-ip>:4950/api/health
MQTT<server-ip>:1883(纯文本)· <server-ip>:1884(TLS)
OPC-UA<server-ip>:11004 · <server-ip>:11005

安全提示:Web 控制台首次登录后,必须更改默认管理员密码。→ 初始密码

运维命令汇总

日常运维使用的命令。均在 /opt/kopens/plantpulse-platform-docker/bin/ 中执行。所有动词支持 --help

任务命令备注
状态检查./status.sh服务/健康状态/卷汇总。0=正常 / 2=异常
运维检查./ops-check.sh容器健康状态 + 健康检查 API + 最近的致命日志
启动./up.sh幂等。0 = 准备就绪
停止./down.sh保留状态
重启./restart.sh优雅排空 → 停止 → 启动 → 等待准备就绪
查看日志./logs.sh [서비스]打印最后 200 行并退出。要追踪请用 -f。无参数则所有容器。列表见 --list
进入容器./shell.sh [서비스]无参数则进入数据湖
更新镜像./update.shpull + 重建。失败时自动回滚到前一镜像
完全删除./remove.sh仅删除容器(保留卷·配置)。RM_IMAGE=1 / RM_NETWORK=1
备份./backup.sh [볼륨 …]默认 pp-data · pp-security
启动验证./stack-verify-boot.sh整体栈准备就绪判定
诊断包./doctor.sh用于支持请求的 tarball。秘密值被屏蔽
修改密码./passwd.sh --list可修改的密钥列表
# 운영 중 빠른 점검 루틴
cd /opt/kopens/plantpulse-platform-docker/bin
./status.sh
./ops-check.sh

# 문제가 의심되면 진단 번들 생성
./doctor.sh
旧名称仍然有效

stack-run.sh · stack-stop.sh · stack-bash.sh · stack-update.sh · stack-remove.sh 未被删除。直接运行会显示新名称,但功能相同。现有客户运维手册无需一次性修改。

警告 — 删除所有卷./tools/remove-all-volumes.sh 会永久删除所有数据。只能在完成备份后使用。

隔离网络(Airgap)安装

在隔离网络环境中分三个步骤安装:获取捆绑包 → 通过介质传输 → 在隔离网络服务器上加载

第 1 步:获取捆绑包

建议的方式是下载 KOPENS 发行的捆绑包

https://product.kopens.io/plantpulse-platform/plantpulse-platform-images-<version>.tar.gz

如果必须在有网络的服务器上直接生成,请使用以下方法。

cd /opt/kopens/plantpulse-platform-docker/bin
./airgap-bundle.sh

# 옵션
INCLUDE_DATALAKE=1 ./airgap-bundle.sh # datalake 이미지까지 포함
OS_TARGET=both ./airgap-bundle.sh # 대상 서버가 Ubuntu인 경우 deb 패키지도 포함 (기본은 RHEL rpm)

产出物是 plantpulse-platform-images-<version>.tar.gz 单个文件,包含以下全部内容:

  • Docker Engine 离线安装包(rpm / deb)
  • 平台镜像(docker save 的结果)
  • repo/ — 安装·运维脚本和 compose/ 全部

第 2 步:传输到隔离网络服务器

通过 USB、内部文件服务器、scp 等允许的介质将 .tar.gz 文件传输到目标服务器。

第 3 步:在隔离网络服务器上加载和安装

sudo -i
mkdir -p /opt/kopens/plantpulse-platform-docker
tar -xzf plantpulse-platform-images-*.tar.gz -C /opt/kopens/plantpulse-platform-docker

cd /opt/kopens/plantpulse-platform-docker/repo/bin
vi env.sh # 3단계 환경 변수 검토와 동일하게 수정
./airgap-load.sh

airgap-load.sh 会自动执行以下操作。

  1. Docker Engine 离线安装(rpm -ivh / dpkg -i) — 已安装则跳过
  2. 平台镜像 docker load
  3. install.sh 调用(SKIP_LOGIN=1 — 镜像已在本地,无需仓库登录)

安装后的启动验证(./up.sh./stack-verify-boot.sh)和运维检查(./ops-check.sh)与手动安装步骤相同。

隔离网络更新

生成包含新版本镜像的捆绑包,按同样步骤传输·加载,然后用 ./update.sh 重建现有容器。

故障排除

preflight 检查失败

消息处理
docker is installed but daemon is not ready while SKIP_OS=1先启动 Docker 守护进程:systemctl start docker。或不带 SKIP_OS 运行,install.sh 会配置 Docker
端口已被占用(WARN)该端口被其他服务占用。用 ss -tlnp | grep :<port> 检查进程,在平台安装前清理
Docker data-root 上层路径不存在(WARN)/data1 目录不存在。将数据磁盘挂载到 /data1 或创建目录

栈无法启动

docker compose up -d 会等待所有 depends_on 条件满足,所以如果有一个容器未通过健康检查,整个命令仅输出一行就失败

dependency failed to start: container plantpulse-server-web is unhealthy

这一行除了容器名外没有任何信息。运维脚本此时会自动同时输出容器列表·状态·健康检查探针输出·各日志尾部,请先阅读这些输出。若要手动检查:

cd /opt/kopens/plantpulse-platform-docker/bin

# 어떤 컨테이너가 어떤 상태인가
./status.sh

# 문제가 있는 컨테이너의 로그
./logs.sh --list # 볼 수 있는 서비스 목록
./logs.sh plantpulse-server-web -n 200

# 자원 상황
df -h
docker stats --no-stream

常见原因:

原因检查
内存不足(OOM)docker inspect <컨테이너> --format '{{.State.OOMKilled}}'。应用级 mem_limit环境变量参考
磁盘已满/data1 可用空间
必需凭据缺失compose 将密码要求为 :?。若为空,栈半启动不了,完全启动不了 — 先运行 install.sh 生成 sidecar
DB 初始化延迟首次安装因模式创建耗时较长。若日志无错误且在进行中,请稍候

若难以确定原因,用 ./doctor.sh 生成诊断包发送给技术支持。诊断包包含所有容器的状态和日志。

TLS 握手显示为 TimeoutException 的情况

应用连接后端时使用的名称若不在证书 SAN 列表中,错误消息中根本不会涉及证书,只看起来像超时。若修改过容器名或直接指定了后端主机,请怀疑这种情况。重新烘焙证书的方法见安全管理

仓库认证失败

# unauthorized 오류 시 재로그인
docker login docker.kopens.io
  • 如果没有登录凭据或凭据已过期,请向 KOPENS 运营团队申请发放。
  • 企业防火墙可能阻止了仓库访问。请向网络管理员申请允许 docker.kopens.ioproduct.kopens.io 域名的 HTTPS 访问。
  • 如果完全禁止外部访问,请使用隔离网络(Airgap)安装

技术支持

安装及运维过程中如需帮助,随时可以联系我们:webmaster@kopens.com