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.sh 和 ops-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 v2(docker 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_CPUS | nproc(读取失败时 8) | 想给容器分配更少核心时 |
DOCKER_PP_CLUSTER_CORES | DOCKER_PP_CPUS - 2,最小 4·最大 30 | 通常保持不变 |
DOCKER_PP_MEMORY | 主机 RAM 的90%,最小 8G | 想为 OS 保留更多空间时 |
DOCKER_DATALAKE_MEMORY | 80G。如果主机更小则为 RAM 的 90% | 调整数据湖上限 |
DOCKER_PP_DATA_DISK_NAME | / 支撑的实际磁盘自动反向推导(失败时 sda) | 自动检测错误时 |
PP_LANG | en | 韩国运营时设为 ko |
PP_TZ | Asia/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 会自动执行整个安装前过程。
- OS 检测及系统配置 — 文件限制(limits)、内核参数(sysctl)、时间同步(chrony)、SELinux 改为 permissive、禁用 swap
- Docker Engine 安装 — 通过 OS 包管理器安装 + 将 data-root 配置为
/data1/docker-data(如果没有 Compose v2 会一起安装) - 防火墙配置 — 开放公开端口(80/443/7443/4949/4950),内部端口仅允许专网段访问
- 生成服务凭据 —
/etc/kopens/plantpulse-platform.env秘密 sidecar 生成(权限 0600,重新运行也不会覆盖现有值) - 仓库登录 —
docker.kopens.io凭据输入(已登录则自动跳过) - 启动栈 — 创建网络/卷 → 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_TIMEOUT | 900 | 等待准备就绪的超时时间(秒) |
PP_READY_INTERVAL | 15 | 检查间隔(秒) |
PP_WAIT=0 | — | 不等待。此时 0 不表示准备完成 |
进程启动本身需要 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) |
常驻容器的健康状态不是 unhealthy | starting / 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" 为 OK 或 WARN 时为正常范围,为 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-security | TLS 证书·密钥库。由 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 接收 |
| 管理 UI | https://<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.sh | pull + 重建。失败时自动回滚到前一镜像 |
| 完全删除 | ./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 会自动执行以下操作。
- Docker Engine 离线安装(
rpm -ivh/dpkg -i) — 已安装则跳过 - 平台镜像
docker load 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.io、product.kopens.io域名的 HTTPS 访问。 - 如果完全禁止外部访问,请使用隔离网络(Airgap)安装。
技术支持
安装及运维过程中如需帮助,随时可以联系我们:webmaster@kopens.com