一、Docker 镜像选择:python:3.10 vs slim vs alpine

1.1 三个版本的核心差异

特性 python:3.10(完整版) python:3.10-slim(精简版) python:alpine(极简版)
基础系统 Debian 完整版 Debian 极简版 Alpine Linux(独立发行版)
C 库 GNU C 库 (glibc) GNU C 库 (glibc) musl C 库
镜像大小 ~900 MB - 1 GB ~180 - 250 MB ~50 - 80 MB
兼容性 最好,适合本地开发 生产环境首选,兼容性好 较差,C扩展包需重新编译
包管理工具 apt-get(包丰富) apt-get(包较少) apk(包极少)

1.2 选择建议

1. 默认选 python:3.10-slim(强烈推荐)

  • 兼具 glibc 的完美兼容性和较小的体积
  • 安装 numpy、pandas、opencv 等 C 扩展包不会报错
  • 生产环境性价比最高的选择

2. 慎用 alpine

  • 虽然基础镜像极小,但 musl C 库与很多 Python 二进制包不兼容
  • 安装含 C 扩展的包时需要重新编译,构建时间极长
  • 编译过程中如果不清理临时文件,最终镜像体积反而可能超过 slim

3. 避免 python:3.10(完整版)

  • 包含大量用不到的 Linux 调试工具(vim、gdb、ssh 等)
  • 体积臃肿(~1GB),浪费存储空间
  • 包含更多潜在安全风险

二、Docker 镜像技术原理(为什么镜像有大小之分)

Docker 镜像采用分层文件系统(UnionFS)和写时复制(Copy-on-Write)机制:

1. 分层结构
Dockerfile 中的每条指令(FROM、RUN、COPY)都会生成一个只读层,每一层只记录与上一层的差异部分(新增、修改、删除的文件)。

2. 写时复制
容器运行时,会在只读层之上临时加盖一层可写层。当修改文件时,系统会把这个文件从下层复制到可写层再修改,下层原文件保持不变。

3. 层复用机制
如果拉取 python:3.10 和 python:3.11,它们底层共用的基础层(如操作系统文件)只会下载一次,极大节省存储和传输成本。

镜像体积大的根源:
层数越多、每一层遗留的临时文件(如 apt-get install 留下的缓存)越多,镜像就越重。这就是 python:3.10 比 slim 和 alpine 大得多的原因。

三、减小镜像体积的 Dockerfile 写法

利用分层原理,通过合并指令和清理缓存来避免中间文件残留:

# 推荐使用 slim 基础镜像
FROM python:3.10-slim

# 关键技巧:将更新、安装、清理合并到同一层(同一 RUN 指令)
RUN apt-get update && \
    apt-get install -y --no-install-recommends gcc build-essential && \
    pip install --no-cache-dir -r requirements.txt && \
    apt-get purge -y gcc build-essential && \
    apt-get autoremove -y && \
    rm -rf /var/lib/apt/lists/*

四、Docker 清理命令详解

4.1 常用清理命令

命令 作用 说明
docker image prune -f 清理无用虚悬镜像 主要清理 rebuild 产生的 <none>:<none> 镜像,推荐使用
docker container prune -f 清理已停止的容器 清理频繁调试遗留的停止状态容器
docker builder prune -f 清理构建缓存 清理 docker build 产生的中间层缓存
docker system prune -f 一键清理(推荐) 一次性完成以上三项清理,效率最高

4.2 执行方式

所有命令都需要在**终端(命令行)**中执行:

  • Windows:PowerShell 或 CMD(可能需要管理员权限)
  • macOS:终端(Terminal)
  • Linux:Bash(Ctrl+Alt+T 快捷打开)

执行时,建议先不带 -f 参数预览将要删除的内容,确认无误后再加 -f 强制执行:

# 预览将清理的内容
docker system prune

# 确认后强制执行
docker system prune -f

4.3 日常维护建议

  1. 立即执行:先运行 docker system prune -f,一次性清理历史积累的垃圾。
  2. 切换基础镜像:将 Dockerfile 中的基础镜像改为 python:3.10-slim
  3. 优化 Dockerfile:使用合并 RUN 指令的方式,减少镜像层数。
  4. 日常维护:定期(如每周)运行 docker system prune -f,保持磁盘空间清洁。

提示:如果想保留构建缓存以加速下次 build,可以只执行 docker image prune -fdocker container prune -f,暂时跳过 docker builder prune -f


五、Docker 代理网络配置

5.1 问题描述

系统代理软件生效后,Docker 守护进程可能无法联网,导致 docker pull 失败。这是因为 Docker 守护进程的网络配置与系统代理相互独立。

5.2 解决方案对比

场景 推荐方案 关键配置
Linux / WSL 2 中的 Docker Engine 为 Docker 守护进程配置代理(systemd) /etc/systemd/system/docker.service.d/http-proxy.conf 中设置环境变量
Windows / macOS 的 Docker Desktop 通过 GUI 设置代理 Settings → Resources → Proxies
仅容器或 docker build 需要代理 配置 Docker 客户端 编辑 ~/.docker/config.json

5.3 方案一:Docker Engine(Linux / systemd)配置

创建配置文件:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<-'EOF'
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=http://proxy.example.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.corp"
EOF

重启 Docker 服务使配置生效:

sudo systemctl daemon-reload
sudo systemctl restart docker

验证配置是否生效:

sudo systemctl show --property=Environment docker

5.4 方案二:Docker Desktop(Windows / macOS)GUI 配置

  1. 打开 Docker Desktop → Settings(设置)
  2. 左侧菜单选择 ResourcesProxies
  3. 开启 Manual proxy configuration
  4. 填写 HTTP/HTTPS 代理地址(如 http://127.0.0.1:7890
  5. Bypass proxy 中添加 localhost,127.0.0.1
  6. 点击 Apply & restart 重启生效

注意:Docker Desktop 中,daemon.json 文件的代理配置会被忽略,必须通过 GUI 设置。

5.5 方案三:Docker 客户端配置(~/.docker/config.json

编辑配置文件,添加 proxies 配置项:

{
  "proxies": {
    "default": {
      "httpProxy": "http://proxy.example.com:3128",
      "httpsProxy": "http://proxy.example.com:3128",
      "noProxy": "*.test.example.com,.example.org,127.0.0.0/8"
    }
  }
}

此配置即时生效,无需重启 Docker,会为后续运行的容器和镜像构建自动注入代理环境变量。

5.6 解决 IP 变化问题的技巧

如果代理地址填的是 WiFi 分配的 192.168.x.x 局域网 IP,每次重启网络可能导致 IP 变化,导致 Docker 代理失效。

推荐解决方案(按优先级排序):

  1. 使用 127.0.0.1:关闭代理软件的“Allow LAN”选项,让它只监听 127.0.0.1,并在 Docker 中填写 http://127.0.0.1:端口。该地址是回环地址,永不变化。
  2. 使用 Docker Desktop 专用域名:对于 Docker Desktop(Windows/macOS),在代理地址中使用 http://host.docker.internal:端口。该域名在容器内自动解析为宿主机真实 IP。
  3. 动态获取 IP(WSL 2 / Linux 环境):在 WSL 2 中执行 cat /etc/resolv.conf | grep nameserver | awk '{print $2}' 获取宿主机 IP,并配合启动脚本自动更新代理配置。
  4. 设置路由器静态 IP:为电脑在路由器中设置 DHCP 保留,确保每次获得相同的局域网 IP。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐