用途
该技能用于创建、审查和调试 Docker 镜像与 Compose 环境,目标是实现可复现构建、安全性、健康检查、配置与效率。
触发场景包括:编写或审查 Dockerfile、docker-compose.yml、.dockerignore、标签/仓库策略;调试无法构建、无法启动或不响应健康检查的容器;缩减镜像体积;消除镜像层中泄露的密钥;修正无法正确接收 SIGTERM 的进程。
不触发场景:多节点编排、带副本的滚动发布、集群密钥、overlay 网络——这些应使用 $specsfy-specialist-docker-swarm。此处的 Docker Compose 指本地/CI 环境,不是多主机生产拓扑。
可与 $specsfy-specialist-application-security 结合进行供应链审查(SBOM、来源、漏洞依赖),并与项目语言/框架技能结合处理构建内容本身。
主要能力与流程
- 在提出变更前,先了解目标架构(amd64/arm64)、基础运行时(语言、版本)、真实构建上下文和预期执行契约(变量、端口、卷)。
- 检查项目已使用的 Dockerfile、.dockerignore、docker-compose.yml 及镜像/标签策略。
- 当镜像属于发布或部署的一部分时,在 $specsfy-specialist-deploy 下执行此步骤;使用 $specsfy-specialist-versioning 提供的版本,用 docker-tag 生成引用,并在 verify-docker-tag 指出差异时拒绝该引用。
- 用清晰的多阶段构建分离构建依赖与运行时依赖——最终镜像不应包含编译器、包缓存或不在生产运行的源码。
- 以可复现方式固定产物(lockfile、固定基础镜像版本或按 digest),缩减构建上下文和可变层。
- 以非 root 用户运行进程,限制权限(cap_drop、不使用 --privileged),绝不将密钥嵌入镜像。
- 明确定义 healthcheck、信号处理(SIGTERM、SIGINT)、卷、网络和外部配置(env、挂载文件)。
- 构建镜像、扫描漏洞,并完全按生产运行方式测试(相同用户、相同变量)。
标准做法
- 对含原生扩展的应用,按族系将编译拆分为独立阶段,避免 Redis、媒体或应用服务器的一处改动使整个工具链失效。
- 多个服务共用同一代码时,生成单一镜像并在 entrypoint 选择进程模式(HTTP、调度器、队列、WebSocket),每种模式配以与其职能兼容的健康检查、信号和写入方式。
- 为 SemVer 和 commit 发布不可变引用,确认两者尚不存在,并记录部署使用的 digest。Git 标签应仅在镜像已在 registry 可用后发布。
- 当框架缓存依赖运行时提供的配置时,在 entrypoint 生成缓存;不要将构建期间创建的配置缓存带到值不同的环境。
- 优先使用兼容的最小基础镜像(栈支持时用 slim/alpine),当逐字节可复现比自动补丁更新更重要时按 digest(@sha256:...)固定。
- 排列指令以最大化缓存(依赖在源码之前),同时不隐藏依赖更新——COPY package*.json 后 RUN install 再 COPY . . 可缓存安装,代码变化时不会冻结已安装版本。
- 使用 BuildKit 的 secret 和 cache 挂载(RUN --mount=type=secret、--mount=type=cache)处理构建凭据和包管理器缓存——绝不用 ARG/ENV 存密钥,因为两者都会保留在最终镜像的层历史中。
- 没有 .dockerignore 时绝不复制整个仓库——.git、node_modules、本地构建产物和 .env 会泄露到上下文并增大体积/构建时间。
- 有意识地处理主进程作为 PID 1:使用 exec 形式的 ENTRYPOINT(["cmd"],而非 shell 形式的 CMD cmd args)以正确接收信号,或当进程不回收僵尸进程时使用最小 init(--init/tini)。
- 将持久数据保持在容器可写层之外(命名卷或 bind mount)——容器层中的数据随容器消亡。
- 在工作负载允许时定义资源限制和只读根文件系统(--read-only + 为需要写入的内容显式挂载卷),减少运行时攻击面。
反模式
- 生产环境仅用 latest 作为标签——不可复现,不检查容器就无法知道运行的是哪份代码。
- 用 ADD 复制本地文件(而非 COPY)——ADD 还会解压和获取 URL,这种隐式行为会让后续阅读 Dockerfile 的人意外。
- 服务流量的镜像中隐式 USER root(缺少 USER)——容器内被攻陷的进程拥有容器 root 权限,放大任何应用漏洞的影响。
- 不用多阶段而在同一最终层安装构建依赖(编译器、头文件)——增大镜像并增加可扫描漏洞面,运行时却无收益。
- 健康检查只验证“进程在监听端口”而不检查关键依赖(数据库、队列)——编排器会认为容器健康,即使它实际无法服务请求。
验证
- 无缓存构建(--no-cache)和增量构建(带缓存)——两者应产生功能等价的镜像。
- 用目标环境的真实用户、架构和环境变量运行镜像,而不仅用开发默认值。
- 演练健康检查、docker stop(在配置期限内优雅关闭)、发布端口、卷、内部 DNS 解析,以及声明的依赖不可用时的行为。
- 生成 SBOM/运行项目可用的漏洞扫描器,检查最终镜像的大小和层数。
- 未运行扫描器不得宣称镜像“安全”,未从同一 commit 重复构建产生相同功能结果不得宣称“可复现”。
相关技能
- $specsfy-specialist-deploy 协调完整交付;此技能仅负责镜像和开发 Compose。
- $specsfy-specialist-versioning 准备 SEMVER 并在发布前核对镜像身份。
- $specsfy-specialist-docker-swarm 用于多节点编排、集群密钥、overlay 网络和服务滚动发布——此专家覆盖镜像和本地 Compose,不覆盖生产集群。
- $specsfy-specialist-application-security 用于供应链(SBOM、来源、依赖 CVE)和容器之外的加固。
- $specsfy-specialist-observability 用于容器内进程的日志、指标和追踪。
- $specsfy-specialist-postgres、$specsfy-specialist-redis 用于镜像/服务内运行的内容(schema 建模、数据结构、持久化)——此技能覆盖打包(官方镜像、卷、健康检查),不覆盖数据库/缓存的内部决策。
- 当项目本地环境由 Supabase CLI 基于 Docker 编排时,使用 $specsfy-specialist-supabase。
- $specsfy-specialist-laravel 用于打包应用的执行契约(队列 worker、调度器、预期环境变量)。
- $specsfy-specialist-debian-server 用于运行镜像的主机的内核、文件系统、systemd、APT 和 Docker Engine。
阅读 references/standards.md 了解构建、Compose、安全、供应链和运维。