17 KiB
生信分析环境 → Docker 镜像构建方法(Playbook)
本文档是把一个 conda 分析环境做成干净 Docker 镜像的标准方法。本次工程先做 8 个镜像(生信流程编排在用的环境),工程结束后其余 18 个环境全部按本方法补做(用户 2026-09-05 指示)。执行 agent 必须在构建过程中回填实测数据,使本文档成为可复用的操作手册。
1. 目标与原则(用户拍板,不可偏离)
- 镜像干净:镜像内只有 root 用户;不存在
/home/xzq或任何宿主机痕迹。 - 一个镜像 = 一个 conda 环境:环境内容与宿主
/home/xzq/miniconda3/envs/<env>对应环境字节级一致(版本漂移为零)。 - 环境即镜像的 Python:环境解包到镜像标准位置
/opt/conda,ENV PATH=/opt/conda/bin:$PATH,python/Rscript/各生信工具由 PATH 直达,不写任何绝对路径。 - 最终镜像无 conda 本体:conda 只作为打包工具出现在构建期,运行时镜像里没有 conda 可执行文件。
- 代码零硬编码:复制进 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
- 后续(2026-09-06 已完成 16 个,见 §8 台账):ani / at_sc / beagle54 / bioinfo / minerupy312 / rice_download / rice_rna / snpeff / testpy311 / vcflinshi / plantai-bff / pymol-env / biolabx-assembly / biolabx-bioinfo-missing / biolabx-smoke-tools / biolabx-variant-tools → 镜像 plantai-env-*:20260906。 豁免 3 个(不建镜像,理由记入 §8):AI_env(12K 空壳仅 conda-meta/etc 目录)、r_de(11M 残壳,r_de_analysis 的旧残留)、miniconda3 base(78G conda 本体,违反「镜像无 conda」红线)
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. 标准流程(每环境)
- 打包:
conda-pack -n <env> -o /tmp/<env>.tar.gz(包内符号链接保留;记录打包时长与 tar 体积) - 选基底:干净基础镜像(如 ubuntu:22.04,按 glibc 对照选版本);基底仅提供 glibc 等系统库,不装任何 conda
- 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、不含源码(明文入口除外)
- 阶段 1:解包
- 验证(§6 清单全过才可发布)
- tag:
bioflow-<name>:<版本或日期> - 发布:本地
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. 常见坑
-
符号链接:conda 环境内部有大量绝对符号链接(→ /home/xzq/miniconda3/pkgs/...),必须用 conda-pack(它把链接目标打包为相对链接),直接
cp -r或tar会坏。 -
前缀硬编码:环境内部分文件(bin 脚本 shebang、pyc、pkg-config .pc)写死源前缀
/home/xzq/miniconda3/envs/<env>——必须conda-unpack重定位,不跑这步的镜像必坏。 -
glibc 不匹配:conda 环境按宿主 glibc 构建,基础镜像 glibc 旧于宿主时二进制缺符号。对照表见 §3。
-
Cython .so 与解释器绑定:内核 .so 必须用镜像内解释器在镜像内编译(3.11 的 .so 在 3.8 解释器下加载必炸);编译是构建期动作,最终镜像不含源码。
-
venv 类环境(pymol-env):非 conda,
pip freeze+python -m venv在镜像内重建,或 venv 目录整体拷贝+sed修 shebang;优先 conda-pack 若其支持(实测记录)。 -
R 环境:conda-pack 对 R 环境同样有效,但 R 包内嵌路径(.libPaths、Renviron)需在验证阶段实跑 Rscript 加载核心包确认。
-
体积: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 可选)。
-
外部软链(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 链接。
-
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。 -
大 tar 零块(2026-09-06 实测新增):>4GB 的 tar.gz 中段出现零块填充,GNU tar 报 "跳转到下一个头"退出码 2 但数据完整。Dockerfile 解包一律
(tar --ignore-zeros -xzf ... || true) && test -x /opt/conda/bin/python断言。 -
ADD 自动解包(2026-09-06 实测新增):
ADD x.tar.gz /path会被解包成目录,必须用 COPY。 -
conda-unpack 的 shebang 是
env python:必须在 ENV PATH 之后单独 RUN,否则 exit 127。 -
docker tag 全小写:bioflow-rnaR → bioflow-rnar(stage_image_map.json 用 docker_tag 字段区分逻辑名与仓库名)。
-
基底拉取:docker.io/nju/rat/1panel 镜像站 blob 端点不通时用
docker.m.daocloud.io/library/ubuntu:24.04。 -
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 包。 -
BuildKit 上下文外软链:docker build 对上下文外绝对软链按上下文根解析失败;stage 目录建在 pack-dir 下用硬链接 tar + rsync 内核源码(源码仅 ~22M)。
-
conda-pack -n 需要 conda 在 PATH(2026-09-06 实测):nohup/后台脚本里
conda-pack -n <env>报CondaPackError: Failed to determine path to environment——它调 conda 解析 env 路径, PATH 里没有 conda 时即失败(-p 路径打包不受影响)。修法:脚本开头export PATH=/home/xzq/miniconda3/bin:$PATH或env PATH=... conda-pack。 -
pip 覆盖检测阻断打包(2026-09-06 实测):env 内 pip 装过 conda 不管理的文件时报
Files managed by conda were found to have been deleted/overwritten(pymol-env 174 个、 minerupy312 多个)。这些是宿主既有历史,非本次改动——加--ignore-missing-files打包。 -
无 python 的工具环境(dest-prefix 路线)(2026-09-06 实测,ani/beagle54/rice_rna/vcflinshi): 环境无 bin/python(纯 C/Java/R/perl 工具)时 conda-unpack 无法运行(shebang 是 env python, 装系统 python3 也因包内文本重定位逻辑可跑但绕)。正解:
conda-pack -n <env> -d /opt/conda打包期直接重定位到目标前缀,产物无 conda-unpack;Dockerfile 只需解包+删 conda 桩。 -
pip entry point shebang 写死源前缀(2026-09-06 pymol-env 实测):conda-unpack 不重定位 pip 装的 console_scripts(pymol/pip/wheel 等 6 个 shebang 仍是 /home/xzq/...)。 Dockerfile unpack 段统一
sed -i '1s|.*|#!/opt/conda/bin/python|'修复, 最终层断言! grep -rlE '^#!.*home/xzq' /opt/conda/bin构建期拦截。 -
conda-unpack 脚本本体含源前缀:包内 conda-unpack 是文本脚本含源前缀字符串, 重定位完成后必须删(与 conda 桩同批),否则镜像内仍有 /home/xzq 文本痕迹。
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);2026-09-14 修复:补 panfamily 模块(68K,COPY 自 pipeline/panfamily/ 进 site-packages)并删指向宿主路径的 activate.d/panfamily.sh(PYTHONPATH 断链);旧镜像 tag=dev-before-panfamily,新镜像已 load 176 并端到端验证 |
| 8 | r_de_analysis | miniconda3/envs | 611M | bioflow-rde | DE 分析 | 已完成(2026-09-06) |
| 9 | AI_env | miniconda3/envs | 12K | — | 空壳(仅 conda-meta/etc) | 豁免:空壳无内容,不建 |
| 10 | ani | miniconda3/envs | 95M | plantai-env-ani | ANI 计算(fastANI, 无 python→dest-prefix) | 已完成(2026-09-06) |
| 11 | at_sc | miniconda3/envs | 8.9G | plantai-env-at-sc | 拟南芥单细胞(R 4.6.1) | 已完成(2026-09-06) |
| 12 | beagle54 | miniconda3/envs | 393M | plantai-env-beagle54 | Beagle imputation(无 python→dest-prefix) | 已完成(2026-09-06) |
| 13 | bioinfo | miniconda3/envs | 295M | plantai-env-bioinfo | 通用生信(bwa) | 已完成(2026-09-06) |
| 14 | minerupy312 | miniconda3/envs | 8.1G | plantai-env-minerupy312 | MinerU 文档解析 | 已完成(2026-09-06) |
| 15 | rice_download | miniconda3/envs | 417M | plantai-env-rice-download | 水稻数据下载(SRA) | 已完成(2026-09-06) |
| 16 | rice_rna | miniconda3/envs | 455M | plantai-env-rice-rna | 水稻 RNA(无 python→dest-prefix, 补 gcc) | 已完成(2026-09-06) |
| 17 | snpeff | miniconda3/envs | 5.1G | plantai-env-snpeff | SnpEff 注释 | 已完成(2026-09-06) |
| 18 | testpy311 | miniconda3/envs | 149M | plantai-env-testpy311 | 测试环境 | 已完成(2026-09-06) |
| 19 | vcflinshi | miniconda3/envs | 79M | plantai-env-vcflinshi | VCF 处理(perl, 无 python→dest-prefix) | 已完成(2026-09-06) |
| 20 | plantai-bff | miniconda3/envs | 553M | plantai-env-plantai-bff | BFF 服务(uvicorn) | 已完成(2026-09-06) |
| 21 | pymol-env | dev 仓库 tools/ | 1.3G | plantai-env-pymol-env | PyMOL 可视化(conda 环境无 pyvenv.cfg, conda-pack -p 打包) | 已完成(2026-09-06) |
| 22 | biolabx-assembly | mamba/envs | 225M | plantai-env-biolabx-assembly | 组装工具(megahit) | 已完成(2026-09-06) |
| 23 | biolabx-bioinfo-missing | mamba/envs | 1.3G | plantai-env-biolabx-bioinfo | QA 测试工具(STAR) | 已完成(2026-09-06) |
| 24 | biolabx-smoke-tools | micromamba/envs | 217M | plantai-env-biolabx-smoke-tools | QA 测试工具 | 已完成(2026-09-06) |
| 25 | biolabx-variant-tools | micromamba/envs | 284M | plantai-env-biolabx-variant-tools | QA 测试工具(bcftools) | 已完成(2026-09-06) |
| 26 | miniconda3 (base) | miniconda3 | 78G | — | conda 本体 | 豁免:含 conda 本体违反镜像红线 |
| 27 | r_de | miniconda3/envs | 11M | — | r_de_analysis 旧残留(conda-meta 4 文件) | 豁免:残壳非独立环境 |
台账中「(待测)」体积与「(待确认)」用途由执行 agent 在构建过程中实测/核实后回填。
10. BIOFLOW_DATA 数据根部署陷阱(2026-09-06 P7 终验实测)
- 容器内断链:数据根 zh/bioflow-data 下的 hmm/ 与 rag_db/pfam_mapping.json 若是 指向宿主其他位置的软链,容器内(挂载进 docker)是断链——identify 报 「本地Pfam映射不存在」+「未能从本地映射或RAG服务获取基因家族Pfam」。
- 处置:挂载进容器的数据必须真实文件(cp -aL 解链复制),不能软链。 已修复:hmm(3.9G 真实文件)+ rag_db/pfam_mapping.json(377B 真实文件)。
- 验证:容器内 ls /bioflow-data/hmm 可见 Pfam-A.hmm* 五文件、 /bioflow-data/rag_db/pfam_mapping.json 可读。
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 |
| ani | 5s | 31M | dest-prefix 免 unpack | 178MB | 23s | fastANI 1.34/CLEAN(无 python 环境) |
| beagle54 | 33s | 271M | dest-prefix 免 unpack | 648MB | 47s | beagle(镜像内 java 自足)/CLEAN(无 python) |
| rice_rna | 3m49s | 549M | dest-prefix 免 unpack | 1.96GB | 1m39s | Rscript/CLEAN(无 python, 补 gcc 系统软链) |
| vcflinshi | 22s | 26M | dest-prefix 免 unpack | 173MB | 22s | perl/CLEAN(无 python) |
| rice_download | 4m30s | 178M | ~10s | 569MB | 1m18s | python 3.10.20/fasterq-dump 3.4.1/CLEAN |
| plantai-bff | 2m14s | 178M | ~10s | 608MB | 1m23s | python 3.11.15/uvicorn 0.52.4/CLEAN |
| bioinfo | 25s | 97M | ~8s | 366MB | 1m6s | python 3.14.5/bwa/CLEAN |
| testpy311 | 31s | 72M | ~8s | 289MB | 1m2s | python 3.11.15/pip/CLEAN |
| snpeff | 9m35s | 1.8G | ~25s | 5.62GB | 4m12s | python 3.14.5/java 11/snpEff/CLEAN |
| at_sc | 15m24s | 4.0G(45%) | ~40s | 9.24GB | ~6min | python 3.11.6/R 4.6.1/CLEAN |
| minerupy312 | 11m58s | 4.3G(53%) | ~40s | 8.58GB | ~5min | python 3.12.13/mineru/CLEAN(--ignore-missing-files) |
| pymol-env | 6m3s | 414M(32%) | ~25s | 1.38GB | 2m36s | python 3.12.13/pymol shebang 修复/CLEAN(--ignore-missing-files) |
| biolabx-assembly | 25s | 80M | ~8s | 298MB | 1m5s | python 3.14.6/megahit/CLEAN |
| biolabx-bioinfo-missing | 1m15s | 410M | ~12s | 1.43GB | 1m41s | python 3.13.14/STAR 2.7.11b/CLEAN |
| biolabx-smoke-tools | 58s | 78M | ~8s | 289MB | 1m4s | python 3.14.6/CLEAN |
| biolabx-variant-tools | 39s | 125M | ~9s | 457MB | 1m10s | python 3.14.6/bcftools 1.23.1/CLEAN |
注: 上表 16 行均为 2026-09-06 实测; 无 python 的 4 环境走 --dest-prefix 打包(免 conda-unpack); 全部 16 镜像通过 §6 清单 + 加强断言(无 conda-unpack 残留、bin 无源前缀 shebang)。