目录
问题背景
前一篇《Polarion-2506-本地开发与30天试用》记录了 2506 的开发环境。Docker 负责安装、提取运行时,并提供 PostgreSQL/Apache。
Polarion Java 仍然由 Eclipse/PDE 启动。
这次重启 Docker 时,我曾经保留了下面三个容器:
1 | |
它们并不是三个独立的 Polarion 环境。三个容器使用相同的镜像、相同的 /opt/polarion 外置挂载目录、相同的 HTTP/数据库端口和同一套 PostgreSQL 数据目录,所以没有必要同时保留。
为什么三个容器都无法启动
三个容器的启动命令都是:
1 | |
逐个执行 docker start -a 时,最后都报:
1 | |
Polarion 的 bin/postgresql-polarion.init 会使用:
1 | |
这个 PID 文件位于容器自己的可写层,不在外置运行目录里。
之前容器退出后,容器层仍然保留了旧 PID;下一次执行 docker start 时,脚本看到 PID 文件就直接走 status。
但这个 PID 已经不对应当前容器中的 PostgreSQL,于是启动脚本以退出码 1 结束,Apache 也不会继续启动。
即使把 stale PID 清掉,三个副本仍然不能并行运行,因为它们会竞争:
- 同一个宿主机 HTTP 端口
25080; - 同一个宿主机 PostgreSQL 端口
25433; - 同一个
data/postgres-data; - 同一个
polarion.properties和 SVN 数据。
因此,正确的修复不是反复点击三个容器的 Start,而是修复入口脚本,并只重建一个依赖容器。
只保留一个依赖容器
现在使用独立仓库维护脚本:
Polarion_Docker_Development_Environment
仓库中的 polarion2506/polarion2506-parallel.sh 虽然保留了 parallel 这个历史名称,但它只管理一个 2506 依赖容器 polarion2506-services。
这里的 parallel 指它可以和已有的 Polarion 22R1 容器共存,不是指创建多个 2506 副本。
清理旧副本时,只删除容器对象,不删除外置数据:
1 | |
不要加 -v,也不要删除:
1 | |
最终保留:
1 | |
重建镜像和运行目录的区别
重建镜像
镜像中已经加入 stale PID 的安全处理:启动 PostgreSQL 前会检查 /var/run/polarion/pg.pid,只有当 PID 无效、对应进程不是 PostgreSQL,或不是当前 data/postgres-data 时才删除它。
Dockerfile 也显式安装了 procps,供进程检查使用。
在仓库目录中构建:
1 | |
脚本使用 Docker BuildKit named context 读取外部安装包。安装包不会复制到 Git 仓库中;默认文件名是:
1 | |
如果客户包文件名不同,可以在 .env.local 修改 POLARION2506_PACKAGE_NAME。
重建镜像不会删除、覆盖或自动还原外置运行目录。它只更新 polarion:2506-installer 镜像。
重新提取运行时
如果需要在一个新的空目录安装 Polarion 2506:
1 | |
它把安装结果写入 POLARION2506_RUNTIME,但不会启动常驻依赖服务。脚本会拒绝覆盖一个非空且不是 Polarion 2506 的目录;不要为了修复 stale PID 删除整个 data 目录。
重建唯一依赖容器
镜像重建后,停止的旧容器仍可能使用旧的 entrypoint。日常启动脚本会自动处理这种情况:
1 | |
它的行为是:
polarion2506-services已运行:只显示状态,不重复创建;- 容器已停止:删除旧容器层并重新创建;
- 只执行
docker rm,不执行docker rm -v; - 外置的 Polarion、SVN 和 PostgreSQL 数据仍然保留。
如果需要明确强制重建正在运行的依赖容器:
1 | |
macOS ARM 修复
2506 安装包中的图表和公式渲染器带有 Linux x86_64 Node。宿主机是 Apple Silicon 时,Eclipse/PDE 启动 Java 后会执行这个文件,典型错误是:
1 | |
容器是 Linux,Eclipse 是 macOS 宿主机进程,因此不能在 Linux Dockerfile 中写入 macOS Node。
运行时提取到外置磁盘后,只替换插件目录中的 node/bin/node,保留 Polarion 自己的 JS 文件和 node_modules:
1 | |
脚本会先把原始文件备份为:
1 | |
POLARION_NODE_SOURCE 必须是 macOS arm64 的 Node 18.x。Intel Mac 或 Linux 主机不要执行这个 macOS 宿主机替换步骤。详细背景见《Polarion-Arm-环境修复》。
日常使用
启动依赖服务
1 | |
默认端口:
| 服务 | 端口 | 说明 |
|---|---|---|
| Apache HTTP | 25080 |
容器提供的访问入口 |
| PostgreSQL | 25433 |
宿主机访问容器内 5433 |
| Eclipse/PDE AJP | 25089 |
2506 Java 进程监听 |
| Eclipse/PDE control | 25087 |
2506 Java control 端口 |
| notification | 40608 |
2506 Java 通知端口 |
启动 Java 应用
依赖容器正常后,再在 Eclipse 中启动外置运行目录里的 Polarion2506.launch。
当前方案仍然由 Eclipse/PDE 启动 Java,这样可以继续使用 target platform、插件开发和断点调试;容器不会自动执行 Polarion Java。
如果 Eclipse 提示“工作空间已经被占用”,先不要删除锁文件。通常是之前的 Eclipse/PDE launch 还在运行,正在持有:
1 | |
先查实际持有者:
1 | |
如果能看到 Java PID,说明 Polarion 已经启动,直接使用当前实例,或在 Eclipse 的 Debug/Console 视图中点击 Terminate 后再启动。只有确认 Java 已退出、lsof 没有输出后,才能清理残留锁:
本次现场通过 lsof 确认,锁文件由宿主机 Java PID 77314 持有。该进程命令行包含 -Declipse.pde.launch=true、-application com.polarion.core.boot.app 和 2506 runtime 的 -data 工作区。
因此这不是容器自动启动导致的重复 Java,而是之前的 Eclipse/PDE 实例仍在运行。此时直接访问 http://localhost:25080/polarion/ 即可;本次验证返回 HTTP 200。
1 | |
截图中在 Docker 容器里执行 /opt/polarion/bin/polarion.init stop,不会停止宿主机 Eclipse 启动的 Java;当前 host/Eclipse 模式不需要使用这个命令。
停止服务
1 | |
只停止容器,不删除容器对象。下一次执行 start 时,如果容器处于停止状态,脚本会重建容器层,以避免再次复用 stale PID。
查看状态和日志:
1 | |
在其他电脑复用
其他电脑只需要重新准备本机路径,不需要把 Polarion 安装包提交到仓库:
1 | |
.env.local、安装 ZIP、运行目录和 Node 二进制已经在 .gitignore 中排除。
每台电脑可以使用不同的外置磁盘路径和端口,但同一台电脑上同一个运行目录只应绑定一个 polarion2506-services。
总结
这次故障的关键点有三个:
- 三个容器其实共享同一个 Polarion 2506 运行目录和端口,不应该并行创建。
- stale
/var/run/polarion/pg.pid属于旧容器层;修复入口脚本后必须重建容器,不能只反复docker start。 - Docker 重建、外置运行目录、macOS ARM Node 修复和 Eclipse Java 启动是四个独立步骤。
以后只需要记住这一条主线:
1 | |