应选用官方、版本固定且精简的基础镜像,如python:3.11-slim-bullseye或alpine,禁用latest标签;通过多阶段构建分离编译与运行环境,以非root用户运行,并集成trivy扫描与镜像签名验证。

选官方且版本固定的镜像
永远避开 latest 标签——它像定时炸弹,随时可能引入不兼容变更或新漏洞。优先使用 Docker Hub 上标记为“Official”(官方)的镜像,并明确指定版本号或摘要。
-
FROM python:3.11-slim-bullseye比FROM python:latest可靠得多 - 更进一步,用镜像摘要锁定:
FROM python@sha256:abc123...,杜绝任何篡改或镜像仓库污染风险 - 避免使用来源不明的第三方镜像,尤其那些名字花哨、更新停滞、无文档说明的
优先使用最小化基础镜像
体积越小,攻击面越窄。不是所有服务都需要完整的 Linux 发行版。
- Alpine:5MB 左右,轻量但注意 musl libc 兼容性(尤其涉及 C 扩展的 Python 或 Node.js)
-
slim(如
debian:slim):剔除了 docs、man、perl 等非运行必需组件,保留 apt,兼容性好于 Alpine - distroless:仅含运行时依赖,无 shell、无包管理器,适合 Go/Java 静态二进制,安全性极高
-
scratch:真正空白,只适合已静态编译、完全自包含的程序(如 Go 编译后加
-ldflags '-s -w')
构建阶段就隔离权限与依赖
FROM 不只是起点,更是权限和环境的起点。从第一行就开始设防。
- 如果基础镜像支持,立刻创建非 root 用户并切换:
RUN adduser -u 1001 -D appuser && USER appuser - 多阶段构建中,构建阶段可用大镜像(如
golang:1.21),运行阶段必须切到最小镜像(如alpine或distroless) - 运行阶段镜像里不要出现
apt、apk、gcc、curl等工具——它们不是运行所需,而是攻击入口
配合扫描与签名机制
再好的 FROM 也可能自带漏洞,得靠自动化手段兜底。
- CI 流程中集成
trivy image --severity HIGH,CRITICAL myapp:v1.2.0,失败则阻断发布 - 私有仓库(如 Harbor)启用自动扫描 + 高危漏洞(CVSS ≥ 7.0)拦截策略
- 开启 Docker Content Trust(
DOCKER_CONTENT_TRUST=1),确保拉取的镜像经过签名验证,防中间人篡改











