用途
本技能用于编写生产级 Dockerfile,涵盖多阶段构建、安全加固与体积优化,并覆盖本地开发用的 docker-compose、镜像层缓存、健康检查,以及区分 2GB 镜像与 50MB 镜像的实践模式。
适用场景包括:从零编写或改进现有 Dockerfile;为编译型语言(Go、Rust、TypeScript)做多阶段构建;用 Docker Compose 搭建本地开发环境;镜像体积优化(选择基础镜像、层缓存);Docker 安全扫描与加固;开发与生产 Dockerfile 模式;排查容器构建失败;优化 .dockerignore。
不适用于:Kubernetes 部署/编排;云厂商容器服务(ECS、Cloud Run、App Runner);CI/CD 流水线配置;docker-compose 之外的容器网络;Docker Swarm。
主要能力
按语言的生产模式
- Node.js / TypeScript(多阶段):分为依赖、构建、生产三个阶段,使用 node:22-alpine,创建非 root 用户,配置 HEALTHCHECK,以 node dist/index.js 启动。
- Python(uv,最快):基于 python:3.12-slim,从 ghcr.io/astral-sh/uv:latest 复制 uv/uvx,使用 uv sync --frozen --no-dev --no-editable 安装依赖,创建非 root 用户,以 uvicorn 启动。
- Go(多阶段 → distroless):构建阶段用 golang:1.22-alpine,CGO_ENABLED=0 编译并加 -ldflags="-s -w",生产阶段用 gcr.io/distroless/static-debian12,以 nonroot:nonroot 运行。
层缓存策略
规则:按从最不常变到最常变的顺序排列 Dockerfile 指令。每条指令创建一个层,某层变化会导致其后所有层重建。
反模式:先 COPY 再装依赖。新手写法 COPY . . 后 RUN npm install,任何文件变化都会击穿缓存并重装全部依赖;专家写法先 COPY package.json package-lock.json ./ 再 RUN npm ci,最后 COPY . .,仅在依赖变化时击穿缓存。
开发用 Docker Compose
示例包含 app、db(postgres:16-alpine)、redis(redis:7-alpine)服务,使用 target: development、bind mount 热重载、匿名卷保护 node_modules、depends_on 配合 condition: service_healthy,以及 Docker Compose Watch(2024+)的 sync 与 rebuild 动作。
反模式:无健康检查。仅靠 depends_on 只等待容器启动而非服务就绪;应为数据库/缓存服务添加 healthcheck 并在 depends_on 中使用 condition: service_healthy。
镜像体积优化
基础镜像体积参考:node:22 约 1.1 GB(生产禁用);node:22-slim 约 200 MB(需要 apt 包时);node:22-alpine 约 130 MB(默认选择);distroless 约 20 MB(Go/Rust 编译产物);scratch 0 MB(完全静态二进制);chainguard/* 约 10-30 MB(安全加固替代)。
快速优化:apk/apt 使用 --no-cache;合并 RUN 命令减少层;积极使用 .dockerignore(node_modules、.git、.md、.env、dist、coverage、.next)。
安全加固
强制使用非 root 用户;compose 中可设 read_only: true 与 tmpfs /tmp;docker run 使用 --security-opt no-new-privileges;固定镜像 digest 以保证可复现;用 docker scout quickview 或 trivy image 扫描漏洞。
反模式:以 root 运行。容器内 root 意味着容器逃逸后攻击者获得宿主机 root;应创建并切换到非 root 用户,仅在构建阶段安装包时使用 root。检测:docker inspect --format='{{.Config.User}}' image:tag,为空即为 root。
按服务类型的健康检查策略
原则:存活(liveness)而非就绪(readiness)。Docker HEALTHCHECK 只回答“进程是否存活且最低限度可用”,不回答“所有依赖是否可达”。混淆二者会导致级联重启。
- API 服务:/health 端点应在进程可服务 HTTP 时返回 200,不检查数据库连通性,不运行昂贵查询,响应 <100ms。
- Worker/后台任务:使用心跳文件模式,worker 每次成功循环写入时间戳文件,检查文件是否在 1 分钟内更新。
- 静态文件服务器(nginx、Caddy):较短 start period,仅检查能返回页面。
- 数据库容器:使用原生客户端,如 PostgreSQL 用 pg_isready、Redis 用 redis-cli ping、MySQL 用 mysqladmin ping。
调参建议:interval 应用 30s、数据库 10s;timeout 3-5s;start_period 静态 5s、API 10s、数据库 30s、JVM 60s+;retries 应用 3、数据库 5。
使用方式
资料未提供具体的安装命令或调用方式,仅提供了 Dockerfile、docker-compose 示例与决策树。
限制
不覆盖 Kubernetes 编排、云厂商容器服务、CI/CD 流水线配置、docker-compose 之外的容器网络以及 Docker Swarm。