Dockerfile生成器Skill dot-ai-generate-dockerfile

这个技能用于自动生成生产级的Dockerfile和.dockerignore文件,通过分析项目结构、语言、框架和依赖,确保安全性和优化,适用于软件开发中的容器化部署。关键词:Dockerfile, .dockerignore, 生产环境, 安全, 多阶段构建, DevOps, 容器化, 代码分析。

DevOps 0 次安装 0 次浏览 更新于 3/18/2026

名称: dot-ai-生成-dockerfile 描述: 为任何项目生成生产就绪、安全、多阶段的Dockerfile和.dockerignore 用户可调用: true

生成生产就绪的Dockerfile

通过分析项目的结构、语言、框架和依赖,为当前项目生成优化、安全、多阶段的Dockerfile和.dockerignore。

指令

您正在帮助开发人员将其应用程序容器化以进行生产部署。您的任务是通过分析项目结构来生成两个文件:

  1. Dockerfile:生产就绪的多阶段构建,遵循安全最佳实践
  2. .dockerignore:优化的构建上下文配置

关键原则

这些是不可协商的规则,覆盖所有其他指导。

在添加任何内容之前验证一切

绝对规则:在向Dockerfile添加任何指令、配置或功能之前,通过检查实际代码库进行验证。

所需流程

  1. 识别您认为应该添加的内容
  2. 搜索代码库以验证其存在或实际需要
  3. 仅当验证后添加 – 如果无法在代码中找到证据,则不添加
  4. 不确定时询问用户 – 如果无法从代码库分析推断,询问用户而不是猜测

从不假设。始终验证。不确定时询问。仅基于证据的Dockerfile。

彻底性优先于速度:浅薄的分析导致损坏的Dockerfile。在生成任何内容之前:

  • 阅读实际的源文件,不仅仅是文件名或目录列表
  • 如果需要,使用不同查询多次搜索模式
  • 通过其导入和依赖跟踪应用程序入口点
  • 不要停在第一个搜索结果 – 彻底调查
  • 如果分析感觉快速,您可能遗漏了什么

生成正确的Dockerfile花更长时间远优于快速但损坏的Dockerfile。提前花时间。

多架构支持

要求:确保所有Dockerfile指令支持多种架构(amd64、arm64等)。

应用于

  • 基础镜像选择:使用多架构官方镜像
  • 二进制下载:动态检测架构,从不硬编码(amd64、x86_64等)
  • 系统包安装:使用包管理器(自动处理架构)
  • 构建命令:确保跨平台兼容性

Dockerfile必须在不同CPU架构上无需修改即可成功构建。

从不添加HEALTHCHECK

绝对禁止:在任何情况下都不添加HEALTHCHECK指令。

原因

  • 健康端点是应用程序特定的,无法从代码库分析验证
  • 添加未验证的健康检查将导致容器被错误标记为不健康
  • 如果应用程序有健康端点,用户会添加自己的HEALTHCHECK

如果添加HEALTHCHECK,您违反了“验证一切”原则。


最佳实践参考

这些是生成Dockerfile时考虑的最佳实践。仅在项目相关时应用它们 – 并非每个实践都适用于每种情况:

  • 包管理器标志取决于使用哪个包管理器(apt-get vs apk vs 其他)
  • 语言特定指导仅适用于该语言
  • “验证一切”原则覆盖所有:如果实践不适合项目,跳过它

在生成期间使用此部分作为指导和验证参考。

安全

实践 描述
非根用户 创建并运行为专用用户(UID 10001+),从不运行为root
固定镜像版本 使用特定标签如node:20-alpine,从不使用:latest
官方镜像 优先使用Docker官方镜像或可信源的已验证发布者
镜像中无秘密 从不嵌入凭据、API密钥或密码在Dockerfile或ENV指令中
无sudo 不在容器中使用sudo;当需要root访问时明确切换USER
最小包 仅安装应用程序实际所需的包
–no-install-recommends 与apt-get一起使用此标志以防止安装可选包
COPY优先于ADD 始终使用COPY,除非专门需要ADD的tar提取功能;从不使用ADD与URLs
无调试工具 避免在生成镜像中安装curl、wget、vim、netcat,除非应用程序需要
在同一层清理 在与安装相同的RUN命令中移除包管理器缓存
可执行文件由root拥有 应用程序二进制文件应由root拥有但由非根用户执行

镜像选择

实践 描述
最小基础镜像 优先使用alpine、slim、distroless或scratch,而不是完整发行版镜像
多阶段构建 始终将构建依赖与运行时分离;构建阶段 → 运行时阶段
匹配语言需求 编译语言 → distroless/scratch;解释语言 → 带运行时的slim/alpine
从项目派生版本 从项目文件获取语言版本(package.json engines、go.mod等)

构建优化

实践 描述
层缓存 在源代码之前复制依赖清单(package.json、go.mod)
组合RUN命令 使用&&链相关命令以减少层并启用清理
明确COPY 从不使用COPY . .;明确复制仅需要的文件和目录
按更改频率排序 首先放置稳定指令(基础镜像、依赖),最后放置易变指令(源代码)
仅生产依赖 仅安装生产依赖,而不是devDependencies

可维护性

实践 描述
排序参数 按字母顺序排列多行包列表,以便于维护和审查
使用WORKDIR 始终使用WORKDIR更改目录,从不使用RUN cd
CMD的执行形式 使用JSON数组格式:CMD ["可执行文件", "arg1"]以正确处理信号
注释非明显决策 解释为何做出某些选择,而不是命令做什么
OCI标签(可选) 添加元数据标签用于镜像管理(org.opencontainers.image.*)

流程

步骤0:检查现有Dockerfile

在生成任何内容之前,检查项目是否已有Dockerfile。

  1. 在项目根目录查找Dockerfile(也检查变体如Dockerfile.prod
  2. 如果找到,阅读并存储其内容以供步骤2使用
  3. 类似地,检查.dockerignore,如果存在则阅读它

这确定步骤2将生成新文件还是改进现有文件。

步骤1:分析项目结构

通过探索而非模式匹配来识别项目特征。

这些是分析目标,非查找表。以下示例是说明性的 – 对遇到的任何语言、框架或工具链应用相同的分析方法。

  1. 语言检测:探索项目以识别其编程语言。

    • 查找依赖清单文件(例如package.jsongo.modrequirements.txtCargo.tomlGemfilecomposer.jsonmix.exsbuild.sbt等)
    • 检查源文件扩展名
    • 阅读清单内容以理解生态系统
    • 原则:每种语言都有某种形式的依赖声明 – 找到并阅读它
  2. 版本检测:找到所需语言/运行时版本。

    • 在清单文件中搜索版本约束或引擎要求
    • 查找版本文件(例如.node-version.python-version.ruby-version.tool-versions
    • 检查CI配置文件,这些文件通常指定版本
    • 如果项目指定版本 → 使用该确切版本
    • 如果未指定版本 → 在线搜索该语言/运行时的当前LTS/稳定版本
    • 原则:如果指定,使用项目所需版本,否则查找当前推荐版本 – 从不猜测
  3. 框架检测:从依赖和项目结构识别框架。

    • 阅读清单文件中的依赖列表
    • 查找框架特定配置文件
    • 检查项目结构以查找框架约定
    • 原则:框架留下指纹 – 配置文件、目录结构、依赖
  4. 应用程序类型:通过检查入口点和配置确定应用程序类型。

    • Web服务器/API:查找HTTP服务器设置、路由定义、端口绑定
    • CLI工具:查找参数解析、命令定义、bin条目
    • Worker/后台作业:查找队列消费者、计划任务
    • 静态站点:查找构建输出配置,无服务器代码
    • 原则:入口点及其导入揭示应用程序目的
  5. 端口检测:在源代码和配置文件中搜索端口配置。

    • 查找环境变量使用(例如PORTHTTP_PORT
    • 搜索服务器初始化中的硬编码端口号
    • 检查配置文件的端口设置
    • 仅当找到具体证据时才添加EXPOSE
  6. 构建要求:识别项目如何构建。

    • 阅读清单文件以获取构建脚本/命令
    • 识别构建工具(可能是语言标准或第三方)
    • 确定构建输出(编译后的二进制、转译代码、打包资产)
    • 原则:每个需要构建的项目都有构建指令 – 找到它们
  7. 系统依赖:关键步骤 – 缺失运行时二进制会导致静默失败。

    • 搜索代码库以查找执行外部命令或二进制的代码
    • 常见模式:shell执行、子进程调用、exec函数、系统调用
    • 对于每个找到的二进制,验证在运行时需要(不仅仅是构建时)
    • 考虑应用程序实际做什么 – 需要CLI工具、数据库客户端、图像处理器吗?
    • 当不确定某物是否为运行时依赖时,询问用户
  8. 环境变量检测:关键步骤 – 缺失环境变量导致运行时失败。

    • 搜索代码库以查找环境变量访问(每种语言都有读取环境变量的方式)
    • 查找.env.example.env.sample或类似文件,这些文件记录所需变量
    • 检查配置和启动代码以查找环境变量使用
    • 确定哪些变量是必需的(无默认值,应用程序失败)与可选的(有默认值)
    • 对于必需变量,在Dockerfile中设置合理默认值
    • 原则:如果代码读取环境变量,容器可能需要配置它

步骤2:生成或改进Dockerfile

如果无现有Dockerfile → 使用以下模式生成新的多阶段Dockerfile。

如果找到现有Dockerfile → 根据以下最佳实践和检查清单分析它,然后改进:

  1. 根据检查清单评估 – 检查构建器和运行时检查清单中的每个项目
  2. 识别问题 – 安全问题(运行为root、:latest标签)、缺失优化(无多阶段、COPY . .)、可维护性问题
  3. 保留有意定制 – 解释决策的注释、自定义配置、环境特定设置
  4. 编辑以修复问题 – 应用最佳实践,同时保持已正确的现有结构
  5. 解释更改 – 当呈现改进的Dockerfile时,简要说明更改了什么及原因

使用以下模式进行检查清单进行生成和验证。

以下示例显示结构模式,非复制粘贴模板。 根据项目使用的任何语言、包管理器和构建工具调整模式。

阶段1:构建器

# 构建阶段 - 为此语言使用带构建工具的镜像
FROM <语言镜像>:<版本>-<变体> AS builder

WORKDIR /app

# 模式:首先复制依赖清单以进行层缓存
# 示例:package.json、go.mod、requirements.txt、Gemfile、Cargo.toml、pom.xml
COPY <依赖清单文件> ./

# 模式:安装依赖,在同一层清理缓存
# 使用项目使用的任何包管理器
RUN <安装依赖命令> && \
    <清理缓存命令>

# 模式:仅复制构建所需的源文件
# 从不使用“COPY . .” – 明确需要什么
COPY <源目录> ./
COPY <构建所需的配置文件> ./

# 模式:运行项目的构建命令
RUN <构建命令>

构建器阶段检查清单

  • [ ] 命名阶段(AS builder
  • [ ] 基础镜像适合语言(带构建工具)
  • [ ] 版本从项目文件派生(非假设)
  • [ ] 依赖清单在源代码之前复制
  • [ ] 依赖安装并在同一RUN中清理缓存
  • [ ] 仅复制所需文件(从不COPY . .
  • [ ] 构建命令匹配项目实际使用

阶段2:运行时

# 运行时阶段 - 使用适合语言的最小镜像
# 编译语言:考虑distroless、scratch或alpine
# 解释语言:使用带运行时的slim或alpine变体
FROM <最小运行时镜像>:<版本>

WORKDIR /app

# 模式:创建非根用户(语法因基础镜像而异)
# Alpine使用addgroup/adduser,Debian使用groupadd/useradd
RUN <创建组命令> && \
    <创建用户命令>

# 模式:仅从构建器复制运行时工件
# 复制内容取决于语言:
# - 编译:仅二进制
# - 解释:构建输出 + 运行时依赖 + 最小配置
COPY --from=builder <构建输出> ./
COPY --from=builder <运行时依赖> ./

# 模式:设置所有权给非根用户
RUN chown -R <用户>:<组> /app

# 在暴露端口或设置CMD之前切换到非根用户
USER <非根用户>

# 仅在分析中验证端口时
EXPOSE <端口>

# 模式:使用执行形式以正确处理信号
# 命令取决于此应用程序如何运行
CMD ["<可执行文件>", "<参数>"]

运行时阶段检查清单

  • [ ] 最小基础镜像(适当时为alpine/slim/distroless/scratch)
  • [ ] 创建非根用户(UID 10001+)
  • [ ] 仅从构建器复制运行时工件
  • [ ] 无源代码、测试、构建工具或开发依赖
  • [ ] 设置适当所有权
  • [ ] USER指令在CMD之前
  • [ ] 仅在分析中验证端口时EXPOSE
  • [ ] CMD以执行形式(JSON数组)

系统包安装模式

当需要系统包时,使用适合基础镜像的包管理器。原则始终相同:仅安装所需内容并在同一层清理缓存

常见示例(调整为基础镜像的包管理器):

# apt-get(Debian、Ubuntu)
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        package1 \
        package2 && \
    rm -rf /var/lib/apt/lists/*

# apk(Alpine)
RUN apk add --no-cache \
        package1 \
        package2

# yum/dnf(RHEL、Fedora、CentOS)
RUN yum install -y \
        package1 \
        package2 && \
    yum clean all && \
    rm -rf /var/cache/yum

包安装检查清单

  • [ ] 为基础镜像使用正确的包管理器
  • [ ] 使用标志跳过可选/推荐包(如可用)
  • [ ] 包按字母排序以便维护
  • [ ] 在同一RUN命令中清理缓存
  • [ ] 仅应用程序实际所需的包

步骤3:创建或改进.dockerignore

如果无现有.dockerignore → 基于Dockerfile生成最小化版本。

如果找到现有.dockerignore → 根据Dockerfile的COPY命令审查它:

  1. 移除冗余排除(Dockerfile未复制的目录)
  2. 添加缺失的安全排除(复制的目录内的秘密)
  3. 保持最小化(约10-15行)

基于Dockerfile生成最小化的.dockerignore文件。

由于Dockerfile使用明确COPY命令(非COPY . .),.dockerignore目的有限:

  1. 安全 – 排除可能存在于被复制目录内的秘密模式
  2. 性能 – 排除减慢构建上下文传输的大目录

流程

  1. 审查Dockerfile的COPY命令 – 它复制哪些目录?
  2. 识别这些目录内的安全风险(可能意外存在的秘密文件)
  3. 识别项目中减慢上下文传输的大目录(>1MB)
  4. 仅排除这些项

什么不要排除

不要排除Dockerfile未复制的目录!

如果Dockerfile未复制目录,在.dockerignore中排除它是无意义的冗余。

目标大小

约10-15行最大。 如果.dockerignore超过20行,可能添加了不必要的排除。

步骤4:构建、测试和迭代

目的:在呈现给用户之前验证Dockerfile工作。Dockerfile在验证前未完成。

4.1 构建

构建镜像以验证Dockerfile语法和指令正确:

docker build -t [项目名称]-validation .
  • 如果构建成功 → 继续运行
  • 如果构建失败 → 分析错误,修复Dockerfile,重试

4.2 运行

启动容器以验证应用程序运行:

docker run -d --name [项目名称]-test [项目名称]-validation
sleep 5  # 允许启动时间

检查容器状态:

docker inspect --format='{{.State.Status}}' [项目名称]-test
docker inspect --format='{{.State.ExitCode}}' [项目名称]-test

预期行为取决于应用程序类型(在步骤1中确定):

  • 服务(Web服务器、API、Worker):容器应仍在运行
  • CLI工具 / 单次命令:容器应退出并代码0

如果容器崩溃或意外退出 → 继续日志分析以理解原因。

4.3 日志分析

捕获并分析容器日志:

docker logs [项目名称]-test 2>&1

使用步骤1中对项目的了解分析日志。 您知道:

  • 这是什么语言和框架
  • 应用程序应该做什么
  • 它需要什么依赖
  • 此类应用程序成功启动的样子

使用此上下文确定日志是否指示:

  • 应用程序正确启动,或
  • 有问题(错误、崩溃、缺失依赖、权限问题等)

如果日志指示问题 → 识别根本原因,修复Dockerfile或.dockerignore,重试。

4.4 链接(如可用)

如果安装了hadolint,运行它以捕获Dockerfile最佳实践问题:

hadolint Dockerfile
  • 如果未安装hadolint → 跳过此检查
  • 如果hadolint报告问题 → 评估每个问题,适当修复,重试
  • 某些hadolint警告可能是有意的(基于项目上下文使用判断)

4.5 安全扫描(如可用)

如果安装了trivy,扫描构建的镜像以查找漏洞:

trivy image --severity HIGH,CRITICAL [项目名称]-validation
  • 如果未安装trivy → 跳过此检查
  • 如果trivy报告基础镜像中的HIGH/CRITICAL漏洞 → 考虑不同基础镜像版本或变体是否会有帮助
  • 如果漏洞在应用程序依赖中 → 为用户记下但不要阻止(依赖更新超出Dockerfile范围)

4.6 迭代

如果任何验证步骤失败:

  1. 分析 特定错误消息或行为
  2. 识别根本原因 – 常见问题包括:
    • 缺失文件 → 不正确的COPY命令或过度攻击的.dockerignore
    • 缺失依赖 → 未安装系统包
    • 权限被拒绝 → 所有权或USER指令问题
    • 模块未找到 → 构建步骤不完整或错误文件复制
    • Hadolint警告 → Dockerfile最佳实践问题
  3. 修复 适当文件(Dockerfile或.dockerignore)
  4. 重试 从步骤4.1

最多5次迭代。 如果5次尝试后仍失败:

  • 停止并向用户呈现当前状态
  • 解释什么失败以及尝试了什么修复
  • 请求指导

4.7 清理

始终在验证后清理,无论成功与否:

docker stop [项目名称]-test 2>/dev/null || true
docker rm [项目名称]-test 2>/dev/null || true
docker rmi [项目名称]-validation 2>/dev/null || true

仅在以下情况下继续向用户呈现Dockerfile:

  • 所有验证步骤通过,和
  • 清理完成

输出格式

对于新Dockerfile(无现有文件)

向用户呈现两个文件:

  1. Dockerfile 带有清晰注释解释每个部分
  2. .dockerignore 带有组织部分

生成后提供:

  • 简要解释设计选择(基础镜像、构建阶段、安全措施)
  • 构建命令:docker build -t [项目名称] .
  • 运行命令:docker run -p [端口]:[端口] [项目名称]
  • 镜像大小预期

对于改进的Dockerfile(找到现有文件)

呈现改进的文件并附带更改摘要:

  1. Dockerfile – 改进版本
  2. 更改内容 – 简要列表说明更改了什么及原因:
    • 安全修复(例如,“添加非根用户 – 之前运行为root”)
    • 优化改进(例如,“添加多阶段构建以减少镜像大小”)
    • 最佳实践更新(例如,“更改CMD为执行形式以进行信号处理”)
  3. 保留内容 – 注意保留的有意定制
  4. .dockerignore – 如需要更改的改进版本

对于两种情况

推荐后续步骤(Dockerfile已验证):

  • 集成到CI/CD管道
  • 提交到版本控制

成功标准

Dockerfile检查清单

  • [ ] 成功构建无错误
  • [ ] 使用多阶段构建(构建器 → 运行时)
  • [ ] 运行为非根用户(UID 10001+)
  • [ ] 使用固定版本标签(无:latest
  • [ ] 使用最小基础镜像(alpine/slim/distroless)
  • [ ] 在源代码之前复制依赖清单(层缓存)
  • [ ] 使用明确COPY(无COPY . .
  • [ ] 使用&&组合RUN命令
  • [ ] 在同一层清理包管理器缓存
  • [ ] 使用--no-install-recommends(如果使用apt-get)
  • [ ] 使用执行形式用于CMD(["可执行文件", "参数"]
  • [ ] 无调试工具除非需要
  • [ ] 无秘密或凭据嵌入

.dockerignore检查清单

  • [ ] 最小大小(约10-15行)
  • [ ] 排除复制目录内的秘密
  • [ ] 排除大不必要的目录
  • [ ] 不排除Dockerfile未复制的目录

验证检查清单(步骤4)

  • [ ] 镜像构建成功
  • [ ] 容器启动无崩溃
  • [ ] 日志显示无指示应用程序失败的错误
  • [ ] Hadolint通过(如安装)
  • [ ] Trivy显示无关键基础镜像漏洞(如安装)
  • [ ] 测试容器和镜像已清理

在所有验证检查通过前,不向用户呈现Dockerfile。


示例工作流

新Dockerfile(无现有文件)

  1. 检查:“未找到现有Dockerfile。将生成新的。”
  2. 探索:“让我查找依赖清单… 找到<清单文件>。阅读它以理解生态系统。”
  3. 识别:“这是一个<语言>项目使用<框架/工具>。清单指示版本<X>。”
  4. 跟踪:“入口点是<文件>。通过导入跟踪以理解运行时需求。”
  5. 结构:“多阶段构建:构建器阶段需要<构建工具>,运行时阶段仅需要<运行时工件>。”
  6. 依赖:“搜索外部二进制使用… 找到<二进制>。这需要在运行时镜像中。”
  7. 生成:“创建Dockerfile和.dockerignore。根据最佳实践检查清单检查。”
  8. 构建与测试:“构建镜像… 运行容器… 检查日志…”
  9. 迭代(如需要):“构建失败由于缺失包。添加到Dockerfile并重试…”
  10. 清理与呈现:“验证通过。移除测试工件。这是您的Dockerfile。”

改进现有Dockerfile

  1. 检查:“找到现有Dockerfile。阅读它以分析…”
  2. 分析项目:与上述相同的探索以理解Dockerfile应该做什么。
  3. 评估:“检查现有Dockerfile与最佳实践检查清单…”
    • “❌ 运行为root – 无USER指令”
    • “❌ 使用:latest标签而非固定版本”
    • “✅ 多阶段构建已就位”
    • “✅ 依赖清单首先复制”
  4. 保留:“保持自定义ENV变量和特定端口配置 – 这些似乎是有意的。”
  5. 改进:“添加非根用户,固定镜像版本以匹配项目需求。”
  6. 构建与测试:“构建改进的镜像… 运行容器… 检查日志…”
  7. 迭代(如需要):“容器崩溃 – 日志显示权限错误。修复所有权并重试…”
  8. 清理与呈现:“验证通过。移除测试工件。以下是改进内容。”

关键心态:调查实际项目而非匹配模板。每个项目独特。在验证前不呈现。