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

12 KiB
Raw Blame History

生信分析环境 → 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 参数化模板

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