12 KiB
12 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
- 后续(其余 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. 标准流程(每环境)
- 打包:
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)。
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 |