Files
PlantAI-rag-new/docs/bioflow_image_build_playbook.md
T

151 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 生信分析环境 → Docker 镜像构建方法(Playbook)
> 本文档是把一个 conda 分析环境做成干净 Docker 镜像的标准方法。本次工程先做 8 个镜像(生信流程编排在用的环境),**工程结束后其余 18 个环境全部按本方法补做**(用户 2026-09-05 指示)。执行 agent 必须在构建过程中回填实测数据,使本文档成为可复用的操作手册。
## 1. 目标与原则(用户拍板,不可偏离)
1. **镜像干净**:镜像内只有 root 用户;不存在 `/home/xzq` 或任何宿主机痕迹。
2. **一个镜像 = 一个 conda 环境**:环境内容与宿主 `/home/xzq/miniconda3/envs/<env>` 对应环境**字节级一致**(版本漂移为零)。
3. **环境即镜像的 Python**:环境解包到镜像标准位置 `/opt/conda`,`ENV PATH=/opt/conda/bin:$PATH`,`python`/`Rscript`/各生信工具由 PATH 直达,不写任何绝对路径。
4. **最终镜像无 conda 本体**:conda 只作为打包工具出现在构建期,运行时镜像里没有 conda 可执行文件。
5. **代码零硬编码**:复制进 rag-new 的代码中宿主机绝对路径全部适配(PATH 裸命令/sys.executable),新写代码一律环境变量/配置。
## 2. 适用范围
- **本次(8 个)**:test4py311(16G)→bioflow-gf / gfpy312(5.4G)→bioflow-gfpy / rnaseq(6.1G)→bioflow-rnaseq / rnaR(2.7G)→bioflow-rnaR / ASAW(5.1G)→bioflow-wgs / interproscanpy311(750M)→bioflow-interproscan / panfamily(1.8G)→bioflow-pan / r_de_analysis(1.6G)→bioflow-rde
- **后续(其余 18 个环境,见 §8 台账)**:AI_env / ani / at_sc / beagle54 / bioinfo / minerupy312 / rice_download / rice_rna / snpeff / testpy311 / vcflinshi / plantai-bff / pymol-env(venv) / biolabx-assembly / biolabx-bioinfo-missing / biolabx-smoke-tools / biolabx-variant-tools / miniconda3(base)
## 3. 前置检查
- [ ] 宿主机 conda-pack 可用(`conda-pack --version`;不可用则 `conda install -c conda-forge conda-pack`)
- [ ] docker 可用且当前用户有构建权限(`docker info`)
- [ ] 磁盘空间 ≥ 环境体积 × 4(tar + 镜像层 + 构建缓存)
- [ ] glibc 对照:`ldd --version`(宿主)vs 基础镜像 glibc——**基础镜像 glibc 必须 ≥ 宿主 glibc**,否则 conda 二进制无法运行
- [ ] 非标准环境先分类:pymol-env 是 venv 非 conda(打包方式见 §7 坑 5);biolabx-* 在 mamba/micromamba 目录(conda-pack 同样适用,注意源路径)
## 4. 标准流程(每环境)
1. **打包**:`conda-pack -n <env> -o /tmp/<env>.tar.gz`(包内符号链接保留;记录打包时长与 tar 体积)
2. **选基底**:干净基础镜像(如 ubuntu:22.04,按 glibc 对照选版本);基底仅提供 glibc 等系统库,不装任何 conda
3. **Dockerfile 多阶段**(参数化模板见 §5):
- 阶段 1:解包 `<env>.tar.gz` 到 `/opt/conda` → `conda-unpack` 重定位前缀 → `ENV PATH=/opt/conda/bin:$PATH`
- 阶段 2(仅内核镜像需要):COPY 内核源码 → 用镜像内解释器 `/opt/conda/bin/python` 跑 build.sh 编译 .so
- 最终阶段:只留 /opt/conda + .so + 明文入口 + 模板/R 脚本等资源;**不含 conda、不含源码**(明文入口除外)
4. **验证**(§6 清单全过才可发布)
5. **tag**:`bioflow-<name>:<版本或日期>`
6. **发布**:本地 `docker build`;跨机 `docker save -o bioflow-<name>.tar <image>` / `docker load`
## 5. Dockerfile 参数化模板
```dockerfile
ARG BASE_IMAGE=ubuntu:22.04
FROM ${BASE_IMAGE} AS unpack
ARG ENV_TAR
ADD ${ENV_TAR} /tmp/env.tar.gz
RUN mkdir -p /opt/conda && \
tar -xzf /tmp/env.tar.gz -C /opt/conda && \
/opt/conda/bin/conda-unpack && \
rm /tmp/env.tar.gz
ENV PATH=/opt/conda/bin:$PATH
ENV LANG=C.UTF-8
# —— 仅内核镜像需要:编译 .so(用镜像内解释器,.so 与解释器版本绑定)——
# COPY --from=src /app/bioflow_kernel /app/bioflow_kernel
# RUN cd /app/bioflow_kernel && /opt/conda/bin/python build.sh <白名单>
FROM ${BASE_IMAGE}
COPY --from=unpack /opt/conda /opt/conda
ENV PATH=/opt/conda/bin:$PATH
ENV LANG=C.UTF-8
# COPY --from=build /app/bioflow_kernel(仅 .so + 明文入口 + 资源)
USER root
```
## 6. 验证清单(每镜像必过)
- [ ] 容器内 `bin/python --version` 与源环境完全一致(版本号+路径前缀重定位后仍可运行)
- [ ] `ldd /opt/conda/bin/python` 无「not found」缺库(conda-unpack 前必须检查,见 §7 坑 3)
- [ ] 代表性工具 `--help`/`--version` 正常(每环境 3-5 个:如 python/Rscript/blastp/mafft/…)
- [ ] 镜像内无 `/home/xzq` 目录、无 `conda` 可执行文件(干净性断言)
- [ ] 内核镜像:`python -c "import gfa_core.xxx"` 加载 .so 成功
- [ ] 金标/冒烟(有金标的环境):如 bioflow-gf 的 identify 24 ID 集合 diff 全等
## 7. 常见坑
1. **符号链接**:conda 环境内部有大量绝对符号链接(→ /home/xzq/miniconda3/pkgs/...),**必须用 conda-pack**(它把链接目标打包为相对链接),直接 `cp -r` 或 `tar` 会坏。
2. **前缀硬编码**:环境内部分文件(bin 脚本 shebang、pyc、pkg-config .pc)写死源前缀 `/home/xzq/miniconda3/envs/<env>`——**必须 `conda-unpack` 重定位**,不跑这步的镜像必坏。
3. **glibc 不匹配**:conda 环境按宿主 glibc 构建,基础镜像 glibc 旧于宿主时二进制缺符号。对照表见 §3。
4. **Cython .so 与解释器绑定**:内核 .so 必须用镜像内解释器在镜像内编译(3.11 的 .so 在 3.8 解释器下加载必炸);编译是构建期动作,最终镜像不含源码。
5. **venv 类环境**(pymol-env):非 conda,`pip freeze` + `python -m venv` 在镜像内重建,或 venv 目录整体拷贝+`sed` 修 shebang;优先 conda-pack 若其支持(实测记录)。
6. **R 环境**:conda-pack 对 R 环境同样有效,但 R 包内嵌路径(.libPaths、Renviron)需在验证阶段实跑 Rscript 加载核心包确认。
7. **体积**:conda-pack 压缩后约为源环境的 35-96%(本次实测: test4py311 44%/interproscan 46%/
rnaseq 38%/rnaR 39%/ASAW 40%/panfamily 35%/gfpy312 53%/r_de_analysis 96%);最终镜像层可再瘦身(删除 __pycache__/conda-meta 可选)。
8. **外部软链(2026-09-06 实测新增)**:dev 环境存在指向宿主其他位置的符号链接(conda-pack 原样打包成镜像内断链):
- interproscanpy311: bin/interproscan → dev tools/ 外部目录(311M); lib/jvm → /usr/lib/jvm
- rnaseq: bin/STAR* ×14 → ~/.local/share/mamba/envs/biolabx-bioinfo-missing/bin
- test4py311: bin/pdftex → ~/.local/TinyTeX(全树无引用, 可删除)
处置: 宿主侧把目标目录打成 extras tar(不动 dev 仓库),Dockerfile `ARG EXTRAS_TAR` 解包到 /opt/ 后
把断链重指镜像内位置;构建前先 `find env -type l` 排查 out-of-prefix 链接。
9. **pkgs 缓存缺失(2026-09-06 实测新增)**:宿主 miniconda3/pkgs 被清理过时 conda-pack 报
`FileNotFoundError: pkgs/xxx/info/files`。修复: 从 `envs/<env>/conda-meta/*.json` 的 paths_data 重建
info/files(脚本见报告附录),或直接 `conda-pack --ignore-missing-files`。
10. **大 tar 零块(2026-09-06 实测新增)**:>4GB 的 tar.gz 中段出现零块填充,GNU tar 报
"跳转到下一个头"退出码 2 但数据完整。Dockerfile 解包一律
`(tar --ignore-zeros -xzf ... || true) && test -x /opt/conda/bin/python` 断言。
11. **ADD 自动解包(2026-09-06 实测新增)**:`ADD x.tar.gz /path` 会被解包成目录,必须用 COPY。
12. **conda-unpack 的 shebang 是 `env python`**:必须在 ENV PATH 之后单独 RUN,否则 exit 127。
13. **docker tag 全小写**:bioflow-rnaR → bioflow-rnar(stage_image_map.json 用 docker_tag 字段区分逻辑名与仓库名)。
14. **基底拉取**:docker.io/nju/rat/1panel 镜像站 blob 端点不通时用 `docker.m.daocloud.io/library/ubuntu:24.04`。
15. **libgomp(2026-09-06 实测新增)**:blastp/R 依赖 libgomp.so.1,而 conda 环境只带 libgomp.so → .1.0.0
(无 .so.1 链接名)。最终阶段加 `ENV LD_LIBRARY_PATH=/opt/conda/lib`,内核镜像再装 ubuntu libgomp1 包。
16. **BuildKit 上下文外软链**:docker build 对上下文外绝对软链按上下文根解析失败;stage 目录建在
pack-dir 下用硬链接 tar + rsync 内核源码(源码仅 ~22M)。
## 8. 环境总台账(26 个,动态回填)
| # | 环境 | 位置 | 体积 | 镜像 | 用途 | 状态 |
|---|---|---|---|---|---|---|
| 1 | test4py311 | miniconda3/envs | 16G | bioflow-gf | GF 链主环境 | 已完成(2026-09-06) |
| 2 | gfpy312 | miniconda3/envs | 5.5G | bioflow-gfpy | mafft/iqtree/meme | 已完成(2026-09-06) |
| 3 | rnaseq | miniconda3/envs | 5.2G | bioflow-rnaseq | RNA-seq 主链 | 已完成(2026-09-06) |
| 4 | rnaR | miniconda3/envs | 2.8G | bioflow-rnaR | R 汇总绘图 | 已完成(2026-09-06) |
| 5 | ASAW | miniconda3/envs | 5.0G | bioflow-wgs | WGS/GWAS/群体 | 已完成(2026-09-06) |
| 6 | interproscanpy311 | miniconda3/envs | 707M | bioflow-interproscan | 结构域注释 | 已完成(2026-09-06) |
| 7 | panfamily | miniconda3/envs | 1.8G | bioflow-pan | 泛基因家族 pangene | 已完成(2026-09-06) |
| 8 | r_de_analysis | miniconda3/envs | 611M | bioflow-rde | DE 分析 | 已完成(2026-09-06) |
| 9 | AI_env | miniconda3/envs | 12K | — | 空壳(仅目录) | 后续 |
| 10 | ani | miniconda3/envs | 95M | — | ANI 计算 | 后续 |
| 11 | at_sc | miniconda3/envs | 8.9G | — | 拟南芥单细胞 | 后续 |
| 12 | beagle54 | miniconda3/envs | 393M | — | Beagle imputation | 后续 |
| 13 | bioinfo | miniconda3/envs | 295M | — | 通用生信 | 后续 |
| 14 | minerupy312 | miniconda3/envs | 8.1G | — | MinerU 文档解析 | 后续 |
| 15 | rice_download | miniconda3/envs | 417M | — | 水稻数据下载 | 后续 |
| 16 | rice_rna | miniconda3/envs | 455M | — | 水稻 RNA | 后续 |
| 17 | snpeff | miniconda3/envs | 5.1G | — | SnpEff 注释 | 后续 |
| 18 | testpy311 | miniconda3/envs | 149M | — | 测试环境 | 后续 |
| 19 | vcflinshi | miniconda3/envs | 79M | — | VCF 处理 | 后续 |
| 20 | plantai-bff | miniconda3/envs | 553M | — | BFF 服务 | 后续 |
| 21 | pymol-env | dev 仓库 tools/(venv) | 1.3G | — | PyMOL 可视化 | 后续 |
| 22 | biolabx-assembly | ~/.local/share/mamba/envs | 225M | — | QA 测试工具 | 后续 |
| 23 | biolabx-bioinfo-missing | ~/.local/share/mamba/envs | 1.3G | — | QA 测试工具 | 后续 |
| 24 | biolabx-smoke-tools | ~/.local/share/micromamba/envs | 217M | — | QA 测试工具 | 后续 |
| 25 | biolabx-variant-tools | ~/.local/share/micromamba/envs | 284M | — | QA 测试工具 | 后续 |
| 26 | miniconda3 (base) | miniconda3 | 78G | — | conda 本体 | 后续 |
> 台账中「(待测)」体积与「(待确认)」用途由执行 agent 在构建过程中实测/核实后回填。
## 9. 构建实测记录(执行 agent 回填)
| 环境 | conda-pack 时长 | tar 体积 | 解包+unpack 时长 | 最终镜像体积 | 构建总时长 | 验证结果 |
|---|---|---|---|---|---|---|
| test4py311 | 20m39s | 7.1G(压缩比44%) | ~3min(含 --ignore-zeros) | 16.4GB | ~15min(含 .so 编译) | python 3.11.14/ldd 0 缺库/CLEAN/工具+hmmsearch 通过(金标见报告) |
| interproscanpy311 | 1m56s | 343M(46%) | ~6s | 1.18GB | 27s | python 3.11.15/InterProScan 5.78-109.0/java 11/CLEAN |
| gfpy312 | 10m33s | 2.9G(53%) | ~35s | 5.85GB | ~3min | python 3.12.13/CLEAN(mafft 见报告已知限制) |
| rnaseq | 16m52s | 2.0G(38%) | ~45s | 6.58GB | ~3min | python 3.11.15/STAR 2.7.11b/salmon 1.10.3/CLEAN |
| rnaR | 5m37s | 1.1G(39%) | ~30s | 2.93GB | 2m29s | python 3.14.3/R 4.5.2/CLEAN |
| ASAW | 12m40s | 2.0G(40%) | ~40s | 5.43GB | ~4min | python 3.8.18/gatk 4.3.0.0/bwa-mem2/plink 1.90/CLEAN |
| panfamily | 6m55s | 625M(35%) | ~20s | 1.96GB | ~2min | python 3.11.9/mafft/iqtree/fimo/blastp/orthofinder/CLEAN |
| r_de_analysis | 7m13s | 589M(96%) | ~20s | 1.88GB | 3m25s | python 3.14.6/R 4.4.3+DESeq2/CLEAN |