#!/usr/bin/env bash # build_all.sh —— BIOFLOW 8 环境镜像构建脚本(镜像标准形态, 零硬编码) # 方法: docs/bioflow_image_build_playbook.md # 用法: build_all.sh [pack-dir] # pack-dir: 存放 conda-pack 产物 .tar.gz 的目录; # 未传参时取环境变量 BIOFLOW_PACK_DIR, 仍未设置则报错退出(零硬编码)。 set -euo pipefail TARGET="${1:-all}" PACK_DIR="${2:-${BIOFLOW_PACK_DIR:-}}" [[ -n "$PACK_DIR" ]] || { echo "Usage: $0 (or set BIOFLOW_PACK_DIR)" >&2; exit 2; } SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" KERNEL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # 镜像名 -> 源环境 tar(conda-pack 产物命名约定: .tar.gz) IMAGES=(gf gfpy rnaseq rnaR wgs interproscan pan rde) declare -A ENV_TAR=( [gf]=test4py311 [gfpy]=gfpy312 [rnaseq]=rnaseq [rnaR]=rnaR [wgs]=ASAW [interproscan]=interproscanpy311 [pan]=panfamily [rde]=r_de_analysis ) # 宿主外部软链修复 extras(可选, pack-dir 下同名 *.tar.gz 存在即传入 --build-arg EXTRAS_TAR) declare -A EXTRAS=( [interproscan]=interproscan-tool [rnaseq]=star-extras ) build_one() { local img="$1" local env="${ENV_TAR[$img]}" local tar_file="$PACK_DIR/${env}.tar.gz" [[ -f "$tar_file" ]] || { echo "[FAIL] missing pack artifact: $tar_file" >&2; return 2; } # 构建上下文: 临时 stage 目录(kernel-src 只读拷贝 + tar 软链, 避免 ADD 大文件跨文件系统复制) local stage # stage 建在 pack-dir 下(同文件系统): tar 硬链接 + 内核源码 rsync 拷贝, # 规避 BuildKit 上下文外软链解析失败的问题; 源码仅 ~22M, 拷贝开销可忽略 stage="$(mktemp -d "$PACK_DIR/.build.XXXXXX")" ln "$tar_file" "$stage/${env}.tar.gz" local extra_arg=() if [[ -n "${EXTRAS[$img]:-}" && -f "$PACK_DIR/${EXTRAS[$img]}.tar.gz" ]]; then ln "$PACK_DIR/${EXTRAS[$img]}.tar.gz" "$stage/${EXTRAS[$img]}.tar.gz" extra_arg=(--build-arg "EXTRAS_TAR=${EXTRAS[$img]}.tar.gz") fi mkdir -p "$stage/kernel-src" # 排除 __pycache__ 与 dev 历史备份(.bak*/.orig, 含旧版硬编码, 绝不入镜像) rsync -a --exclude '__pycache__' --exclude '*.bak*' --exclude '*.orig' \ "$KERNEL_ROOT/" "$stage/kernel-src/" echo "[BUILD] bioflow-$img ($env) stage=$stage" docker build \ --build-arg BASE_IMAGE="${BIOFLOW_BASE_IMAGE:-ubuntu:24.04}" \ --build-arg ENV_TAR="${env}.tar.gz" \ "${extra_arg[@]}" \ -f "$SCRIPT_DIR/Dockerfile.bioflow-$img" \ -t "bioflow-${img,,}:dev" \ "$stage" rm -rf "$stage" echo "[OK] bioflow-$img" } if [[ "$TARGET" == "all" ]]; then for img in "${IMAGES[@]}"; do build_one "$img" done elif [[ -n "${ENV_TAR[$TARGET]:-}" ]]; then build_one "$TARGET" else echo "Usage: $0 [pack-dir]" >&2 exit 2 fi