news 2026/10/23 9:14:46

使用DockerFile进行docker镜像打包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用DockerFile进行docker镜像打包

1、对python服务进行打包
编写DockerFile

# 私有化 AI Infra 引擎 v2 — 联调(.249 bigDataServer)与线上(.42/.43/.44)**同一镜像**, # 运行时 -e APP_ENV=test|prod 选烧进镜像的双档配置 (二文件合并案 DEPLOY §2 手术件4)。 # base 锁 bullseye (glibc 2.31): CentOS7 kernel 3.10+seccomp 拦 glibc>=2.34 的 clone3 → pthread EPERM # (DEPLOY §5 头号坑, 两台宿主均 CentOS7; 万一必须升 base, 退路 --security-opt seccomp=unconfined) # docker.io 海外直连慢/不稳 (10-20 .249 实测拉取 4 分钟): 从零构建的机器可换国内前缀 # FROM docker.m.daocloud.io/library/python:3.11-slim-bullseye — 同一枚镜像走 DaoCloud 公共代理 FROM python:3.11-slim-bullseye ENV PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PYTHONUTF8=1 \ TZ=Asia/Shanghai \ APP_ENV=test # 10-20 D4 两级实测, apt 层整体绕掉: ①.249 出口到 deb.debian.org(Fastly 境外)80 不通; # ②换阿里云后索引通但 bullseye-security 文件 404 (Debian11 已 2026-08 停止常规支持, 镜像池清空索引滞后)。 # 原 apt 只为装 curl(HEALTHCHECK 用)+tzdata(base 镜像 python:3.11-slim 自带): # curl → 健康检查改 python urllib (镜像内必有); tzdata → 仅剩时区软链, ln 即可 RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime WORKDIR /app COPY requirements.txt . # torch 先走 CPU 专用索引: PyPI 默认轮=CUDA 捆绑 (+5GB, 破 "全量 2~3GB" 打包结论); # 装得 2.13.0+cpu 后, 后续 requirements 的 torch==2.13.0 按 PEP440 视为已满足不再回拉 # 10-20 用户口径「海外源大概率不通, 尽量国内」: torch 轮走上交大 pytorch-wheels 镜像 # (备选 南大 https://mirror.nju.edu.cn/pytorch-wheels/cpu); pypi 走阿里云; # 国内镜像若同步滞后缺 2.13.0 版本 → 回退官方 https://download.pytorch.org/whl/cpu (443 实测可达) RUN pip install --index-url https://mirror.sjtu.edu.cn/pytorch-wheels/cpu torch==2.13.0 \ && pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ COPY . . EXPOSE 10021 # 健康检查不依赖 curl (apt 层已绕掉, 见上): 用镜像内 python 打 /health, 200=healthy HEALTHCHECK --interval=30s --timeout=5s --start-period=120s \ CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:10021/health',timeout=4).getcode()==200 else 1)" # SERVER_HOST/PORT(10021) 由 config 读 .env.{APP_ENV}; Linux 默认可用 proactor-free 循环, # run.py 的 Selector 策略仅 win32 生效 — 容器内与开发机同一条启动入口 CMD ["python", "run.py"]

Dockerfile 逐行代码解析

联调(.249 bigDataServer) 与 线上(.42/.43/.44) · 同一镜像

运行时 -e APP_ENV=test|prod 选烧进镜像的双档配置(二文件合并案 DEPLOY §2 手术件4)

──────────────────────────────────────────────────

一、基础镜像选型与 glibc 兼容性说明

# base 锁 bullseye (glibc 2.31): CentOS7 kernel 3.10+seccomp 拦 glibc>=2.34 的 clone3 → pthread EPERM

# (DEPLOY §5 头号坑, 两台宿主均 CentOS7; 万一必须升 base, 退路 --security-opt seccomp=unconfined)

# docker.io 海外直连慢/不稳 (10-20 .249 实测拉取 4 分钟): 从零构建的机器可换国内前缀

# FROM docker.m.daocloud.io/library/python:3.11-slim-bullseye — 同一枚镜像走 DaoCloud 公共代理

FROM python:3.11-slim-bullseye

【解析】本 Dockerfile 服务于"私有化 AI Infra 引擎 v2"项目。该镜像同时用于联调环境和线上环境(服务器 IP 尾缀分别为 .249、.42、.43、.44)。通过 Docker 运行时环境变量 APP_ENV 取值 test 或 prod 来切换配置档位,属于 DEPLOY 文档第 2 节"手术件 4"中定义的二文件合并方案。

基础镜像锁定 Debian 11 "bullseye",其内置 glibc 2.31。原因是部署宿主机均为 CentOS 7(内核 3.10),该内核的 seccomp 安全策略会拦截 glibc >= 2.34 引入的 clone3 系统调用,导致 pthread 创建线程时报 EPERM(权限拒绝)错误——这是 DEPLOY 文档第 5 节标注的"头号坑"。万一未来必须升级到更高版本的基础镜像,应急方案是启动容器时添加 --security-opt seccomp=unconfined 以关闭 seccomp 过滤(降低安全性,仅应急用)。

Docker Hub 默认域名 docker.io 在国内直连速度慢且不稳定,在 .249 服务器上实测拉取一次需要 4 分钟。对于从零构建镜像的机器,可以将 FROM 行替换为 DaoCloud 公共代理前缀:FROM docker.m.daocloud.io/library/python:3.11-slim-bullseye,两者指向同一枚官方镜像,只是通过国内镜像加速器拉取,速度更快。

──────────────────────────────────────────────────

二、环境变量定义

ENV PYTHONUNBUFFERED=1 \

PIP_NO_CACHE_DIR=1 \

PYTHONUTF8=1 \

TZ=Asia/Shanghai \

APP_ENV=test

【解析】设置以下环境变量:
PYTHONUNBUFFERED=1:关闭 Python 输出缓冲,确保日志实时写入容器 stdout,便于 docker logs 查看;
PIP_NO_CACHE_DIR=1:pip 不缓存下载包,减小镜像体积;
PYTHONUTF8=1:强制 Python 使用 UTF-8 编码,避免中文乱码;
TZ=Asia/Shanghai:设置容器时区为上海(东八区);
APP_ENV=test:应用运行环境标识,默认 test;运行时可通过 -e APP_ENV=prod 覆盖为生产环境。

──────────────────────────────────────────────────

三、apt 源问题说明(为何跳过 apt install)

# 10-20 D4 两级实测, apt 层整体绕掉: ①.249 出口到 deb.debian.org(Fastly 境外)80 不通;

# ②换阿里云后索引通但 bullseye-security 文件 404 (Debian11 已 2026-08 停止常规支持, 镜像池清空索引滞后)。

# 原 apt 只为装 curl(HEALTHCHECK 用)+tzdata(base 镜像 python:3.11-slim 自带):

# curl → 健康检查改 python urllib (镜像内必有); tzdata → 仅剩时区软链, ln 即可

【解析】在 .249 和 .42 两台服务器上的实测发现两个问题:
问题①:.249 服务器出口流量无法访问 deb.debian.org(经 Fastly CDN 境外节点)的 80 端口,网络连接被拒。
问题②:更换为阿里云 apt 镜像源后,索引文件虽能连通,但 bullseye-security 仓库的文件返回 404。原因是 Debian 11 已于 2026 年 8 月停止常规支持(EOL),镜像池已清空旧索引但同步有滞后。

结论:直接跳过 apt 安装层。原来 apt 只需装两个包——curl(用于 HEALTHCHECK 健康检查)和 tzdata(时区数据)。但 base 镜像 python:3.11-slim 已自带 tzdata,只需创建时区软链接即可;而 curl 的健康检查功能可改用 Python 内置的 urllib 模块替代(镜像中必然存在)。因此本 Dockerfile 完全不执行 apt-get install,避免网络问题导致构建失败。

──────────────────────────────────────────────────

四、时区设置

RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

【解析】通过符号链接将 /etc/localtime 指向上海时区文件,效果等同于安装了 tzdata 包并设置时区为 Asia/Shanghai。参数 -f 表示强制覆盖已存在的文件,-s 表示创建符号链接。这样容器内所有进程的时间戳均显示为北京时间(UTC+8),且无需额外安装 tzdata 包,减少了镜像层和网络依赖。

──────────────────────────────────────────────────

五、工作目录与依赖文件复制

WORKDIR /app

COPY requirements.txt .

【解析】WORKDIR /app:将容器内的工作目录设置为 /app。后续所有 COPY、RUN、CMD 等指令的相对路径都相对于 /app,也是容器启动后 shell 进入的默认目录。
COPY requirements.txt .:将宿主机当前目录下的 requirements.txt 文件复制到容器工作目录 /app 下。这一步单独复制依赖文件是为了利用 Docker 层缓存机制——如果 requirements.txt 未变,后续的 pip install 层会命中缓存,大幅加快重建速度。

──────────────────────────────────────────────────

六、PyTorch 安装策略说明

# torch 先走 CPU 专用索引: PyPI 默认轮=CUDA 捆绑 (+5GB, 破 "全量 2~3GB" 打包结论);

# 装得 2.13.0+cpu 后, 后续 requirements 的 torch==2.13.0 按 PEP440 视为已满足不再回拉

# 10-20 用户口径「海外源大概率不通, 尽量国内」: torch 轮走上交大 pytorch-wheels 镜像

# (备选 南大 https://mirror.nju.edu.cn/pytorch-wheels/cpu); pypi 走阿里云;

# 国内镜像若同步滞后缺 2.13.0 版本 → 回退官方 https://download.pytorch.org/whl/cpu (443 实测可达)

【解析】PyTorch 的安装策略包含三个关键设计:
策略①(CPU 专用索引):先通过 CPU 专用索引源安装 torch==2.13.0+cpu 版本。如果不指定 CPU 专用索引,PyPI 默认提供的 wheel 包会捆绑 CUDA 运行时库,额外增加约 5GB 体积,破坏"全量镜像 2~3GB"的体积控制目标。
策略②(PEP440 版本匹配):先用 CPU 索引装上 2.13.0+cpu 版本后,后续 requirements.txt 中若声明 torch==2.13.0,pip 按 PEP440 版本匹配规则会认为已满足依赖而不再重新拉取(+cpu 后缀被视为兼容版本)。
策略③(国内镜像源优先级):主选上海交大 pytorch-wheels 镜像,备选南京大学镜像,PyPI 通用源用阿里云,最终兜底为 PyTorch 官方 CPU 轮子(443 端口实测可达)。

──────────────────────────────────────────────────

七、Python 依赖包安装

RUN pip install --index-url https://mirror.sjtu.edu.cn/pytorch-wheels/cpu torch==2.13.0 \

&& pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/

【解析】分两步安装 Python 依赖:
第一步:通过上海交大 pytorch-wheels 镜像源安装 CPU 版本的 PyTorch 2.13.0。--index-url 指定单个索引源(不使用 --extra-index-url,避免混入 CUDA 版本)。
第二步(&& 串联):第一步成功后,通过阿里云 PyPI 镜像安装 requirements.txt 中列出的其余依赖。-i 指定阿里云镜像源加速下载。
两步分开执行的好处是——如果只需更新业务依赖而不改 torch 版本,Docker 可以复用第一步的缓存层,无需重新下载 PyTorch(约 200MB+)。

──────────────────────────────────────────────────

八、复制应用代码

COPY . .

【解析】将宿主机当前目录下的所有文件和目录递归复制到容器工作目录 /app 中。这是最后一步 COPY,因为应用代码变更频率最高,放在最后可以最大化利用 Docker 层缓存——只要 requirements.txt 不变,后续的 pip install 层都会命中缓存。

──────────────────────────────────────────────────

九、端口声明

EXPOSE 10021

【解析】声明容器运行时监听 TCP 10021 端口。注意:EXPOSE 仅做文档声明,不会自动映射端口到宿主机。实际端口映射需在 docker run 时使用 -p 参数完成(如 docker run -p 10021:10021),或在 k8s Deployment 的 service 中配置端口映射。

──────────────────────────────────────────────────

十、健康检查配置

# 健康检查不依赖 curl (apt 层已绕掉, 见上): 用镜像内 python 打 /health, 200=healthy

HEALTHCHECK --interval=30s --timeout=5s --start-period=120s \

CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:10021/health',timeout=4).getcode()==200 else 1)"

【解析】配置容器健康检查(Health Check),让 Docker 引擎定期探测容器是否正常运行:
--interval=30s:每隔 30 秒执行一次健康检查;
--timeout=5s:检查命令执行超过 5 秒视为失败;
--start-period=120s:容器启动后给予 120 秒的宽限期(应用冷启动可能需要较长时间初始化)。
检查命令使用Python 内置的 urllib.request 模块向容器自身 http://127.0.0.1:10021/health 端点发起 HTTP 请求。若返回 HTTP 状态码 200 则标记为 healthy,若返回其他状态码或请求失败则标记为 unhealthy。
不选用 curl 的原因:前面跳过了 apt 安装层(避免网络问题),镜像中没有 curl 命令。Python 标准库的 urllib 在任何 Python 镜像中都内置可用,无需额外安装。

──────────────────────────────────────────────────

十一、容器启动命令

# SERVER_HOST/PORT(10021) 由 config 读 .env.{APP_ENV}; Linux 默认可用 proactor-free 循环,

# run.py 的 Selector 策略仅 win32 生效 — 容器内与开发机同一条启动入口

CMD ["python", "run.py"]

【解析】设置容器启动时执行的默认命令:启动 Python 应用入口文件 run.py。
补充说明:服务器地址和端口(10021)由应用配置文件读取 .env.test 或 .env.prod 文件获取,具体读取哪个文件取决于运行时环境变量 APP_ENV 的值。run.py 中包含的 Selector 策略(事件循环选择器)仅对 Windows 系统生效;在 Linux 容器环境和开发机(通常也是 Linux)上,Python 默认使用 proactor 事件循环,因此容器内和生产开发环境使用同一条启动命令即可,无需区分平台。

──────────────────────────────────────────────────

十二、关键设计决策总结

设计决策

原因

基础镜像选 bullseye

CentOS7 宿主机 kernel 3.10 不兼容 glibc>=2.34 的 clone3 调用

不用 apt install

.249 服务器无法访问 deb.debian.org;阿里云镜像 bullseye-security 文件 404

不用 curl 做健康检查

apt 层已跳过,镜像内无 curl;改用 Python 内置 urllib

torch 走 CPU 专用索引

避免 PyPI 默认 wheel 捆绑 CUDA 运行时(+5GB),控制镜像体积在 2~3GB

国内镜像源优先

海外源大概率不通;主选交大镜像,备选南大/阿里云/官方

时区设置用 ln 软链

不装 tzdata 包也能设置时区,减少镜像层和网络依赖

2、操作命令

tar -xzf pkai_src_v0.1_*.tar.gz

cd /opt/wqo_python/python_knowlage_ai/

docker rm -f ai-agent
docker rmi aiinfra-engine:v0.1

有问题的镜像可以删除


cd /opt/wqo_python/python_knowlage_ai
docker build -t aiinfra-engine:v0.1 .

docker build -t aiinfra-engine:v0.1 .

docker images

先看 10021 是否被占、有无同名残留容器:

docker ps -a --filter name=ai-agent
ss -lntp | grep 10021

1. 开发机推模型(约 809M = rerank 565M + embed 184M + cv 60M):

rz -e

docker rm -f ai-agent
docker 启动命令

docker run -d --name ai-agent --restart=unless-stopped -p 10021:10021 --memory=4g -e APP_ENV=test --log-opt max-size=100m --log-opt max-file=5 -v /opt/wqo_python/models:/app/models:ro -v /opt/wqo_python/logs:/app/logs aiinfra-engine:v0.1

docker run -d --name ai-agent --restart=unless-stopped -p 10021:10021 --memory=4g -e APP_ENV=test --log-opt max-size=100m --log-opt max-file=5 -v /opt/wqo_python/models:/app/models:ro -v /opt/wqo_python/logs:/app/logs aiinfra-engine:v0.1


docker logs -f ai-agent

在本地测试

set PYTHONUTF8=1&& .venv\Scripts\python.exe scripts\smoke_agent_http.py http://192.168.1.249:10021

----------------------------------------------------------------------------------------------------------------

更新镜像的操作

docker run -d --name ai-agent --restart=unless-stopped -p 10021:10021 --memory=4g -e APP_ENV=test --log-opt max-size=100m --log-opt max-file=5 -v /opt/wqo_python/models:/app/models:ro -v /opt/wqo_python/logs:/app/logs aiinfra-engine:v0.1

cd /opt/wqo_python/python_knowlage_ai docker build -t aiinfra-engine:v0.1 . docker rm -f ai-agent docker run -d --name ai-agent --restart=unless-stopped -p 10021:10021 --memory=4g -e APP_ENV=test --log-opt max-size=100m --log-opt max-file=5 -v /opt/wqo_python/models:/app/models:ro -v /opt/wqo_python/logs:/app/logs aiinfra-engine:v0.1 docker images -a | grep aiinfra # v0.1=新ID, 另有一行 <none>=旧镜像 docker image ls -f dangling=true # 单看无名的 # 按 ID 删单枚(最精确, 比如咱自己的旧 v0.1 残影) docker rmi 5f6c03434f78

cd /opt/wqo_python/python_knowlage_ai -------待验证
bash scripts/deploy_test.sh

2、.244 部署方案与计划 -------------待讨论
244上
mkdir -p /opt/wqo_python/{models,logs}

上传 models.zip

unzip models.zip

【镜像搬运】249 上 docker save aiinfra-engine:v0.1 | gzip → scp 244 → docker load(§7 ship 口径,千兆内网约 1 分钟级)。

docker save aiinfra-engine:v0.1

【起容器】照 deploy_test.sh 的 run 段(-e APP_ENV=test、双卷、4g、log-opt)。小手术:给 deploy_test.sh 加个 SKIP_BUILD=1 开关即可复用(当前脚本 build 是死步);不加就手工 run。
【验收】curl :10024:10021/health 全绿 → 开发机 smoke_agent_http.py http://192.168.1.244:10021 36 项 → verify_agent_contract.py --db → 沙盒平方和项(依 248:2375 通)→ eval_rag --limit 2 护基线 0.982/5.000。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 9:06:45

SQL窗口函数实战指南:从分组排名到同比环比的核心用法

忘了从什么时候开始&#xff0c;面试问窗口函数几乎成了数据分析岗的标配&#xff0c;工作中写复杂报表也绕不开它。但说实话&#xff0c;我见过不少做了两三年取数需求的同事&#xff0c;窗口函数还停留在ROW_NUMBER()排序的阶段&#xff0c;碰到"分组内TopN""…

作者头像 李华
网站建设 2026/10/23 9:04:31

Windows 11 或 10:如何删除、创建和格式化分区

本篇教你如何在 Windows 11 或 10 上,对已安装的机械硬盘或 SSD 进行分区的删除、创建或格式化,把它们的全部存储容量认领回来、用起来。 设想你现在的 PC 装了一块传统机械盘,而你现在想再添一块硬盘或 SSD。那新的一块自然用来启动系统,旧的那块就纯粹当数据仓用。等把操…

作者头像 李华
网站建设 2026/10/23 9:03:33

Qt界面美化工程化:QSS、QPainter自绘与无边框窗口

简介&#xff1a;面向Qt初学者与希望提升桌面软件观感的开发者&#xff0c;这份Qt界面美化小工程以可运行源码形式提供按键、提示框、表格等常见控件的定制思路&#xff0c;适合在课程设计、工具软件与小型管理系统中参考复用。压缩包共75个文件、约4.9MB&#xff0c;包含12个c…

作者头像 李华
网站建设 2026/10/23 9:03:20

短剧小程序源码拆包:竖屏剧场搭建、播放权限与自检

简介&#xff1a;面向希望切入短剧市场的前后端开发者与独立搭建者&#xff0c;这套小剧场短剧影视小程序源码提供从内容播放、用户管理到支付接入的一站式实现思路&#xff0c;适合在碎片化观看场景下快速验证付费短剧、会员订阅等业务模式&#xff0c;新手可借教程入门&#…

作者头像 李华