mcpField
D
dockerize

dockerize

github.com/haloydev云与 DevOps050 次安装5 周前更新
代码仓库

关于 dockerize

dockerize 是一项 Agent 技能,用于创建适配 haloy 部署单个服务的 Dockerfile。它会检查项目配置和运行需求,并处理构建阶段、健康检查及部署配置指引。

主要功能

  1. 01识别项目类型与包管理器
  2. 02检查构建和运行需求
  3. 03生成优化的多阶段 Dockerfile
  4. 04检查健康检查端点
  5. 05提供 haloy 配置指引

适用场景

  1. 01为 haloy 部署单个应用构建容器
  2. 02添加包含健康检查的 Dockerfile
  3. 03根据项目文件确定运行时版本
  4. 04准备 Docker 构建与本地测试说明

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/haloydev/agent-skills --skill dockerize

安装后在 Claude Code 中输入/dockerize确认已加载。

附带文件references/base-images.mdreferences/tanstack-start.md

详细介绍

为 Haloy 容器化

创建适用于使用 haloy 部署、已针对生产环境优化的 Dockerfile。

如果用户的请求涉及 docker-compose、多个容器或复杂的编排,请告知他们:

“此技能会创建用于 haloy 部署的单个 Dockerfile。Haloy 的工作方式类似于 docker-compose,但面向生产环境,并通过自身的配置处理编排。如果你需要多个服务,每个服务都应有自己的 Dockerfile,并在 haloy.yaml 中定义为单独的服务。你希望我改为针对某个特定服务创建 Dockerfile 吗?”

工作原理

  1. 检测项目类型,检查以下内容:

    • package.json 中是否包含 @tanstack/react-start(TanStack Start)
    • package.json 中是否包含 next(Next.js)
    • package.json(Node.js/JavaScript/TypeScript)
    • bun.lockb、pnpm-lock.yaml、package-lock.json 或 yarn.lock(Node 包管理器)
    • requirements.txt、pyproject.toml、Pipfile(Python)
    • uv.lock、poetry.lock 或 pyproject.toml 中的 [tool.poetry](Python 包管理器)
    • go.mod(Go)
    • Cargo.toml(Rust)
    • Gemfile(Ruby)
    • pom.xml、build.gradle(Java)
    • composer.json(PHP)
    • 其他指示信息
  2. 分析应用,确定:

    • 构建流程和依赖项
    • 运行时要求
    • 入口点/启动命令
    • 必需的环境变量
    • 静态资源或构建产物
  3. 检查健康检查端点;如果缺失,询问用户是否需要创建(见下方“健康检查”部分)

  4. 创建经过优化的 Dockerfile,遵循最佳实践:

    • 使用多阶段构建来减小镜像体积
    • 选择合适的基础镜像(尽可能使用 Alpine)
    • 合理安排层顺序以提高缓存效率
    • 使用非 root 用户以提升安全性
    • 使用指向健康检查端点的 HEALTHCHECK 指令
  5. 如果不存在 haloy.yaml,提供 haloy 配置指导

健康检查端点

强烈建议所有 haloy 部署都提供 /health 端点。创建 Dockerfile 前,请检查应用是否已有健康检查端点。

健康检查的重要性

Haloy 使用健康检查来:

  • 实现零停机部署:新容器必须通过健康检查后才能接收流量
  • 自动恢复:不健康的容器会自动重启
  • 验证部署:如果应用无法正常启动,部署会快速失败

如果没有健康检查,haloy 就无法确认应用是否正常运行,这可能导致流量被路由到故障容器。

检查现有健康检查端点

搜索现有健康检查端点:

  • /health、/healthz、/api/health、/_health
  • 查找返回状态码 200 或 { status: "ok" } 的路由定义
询问用户

如果不存在健康检查端点,请询问用户:

“你的应用似乎没有健康检查端点。Haloy 使用健康检查来实现零停机部署和自动恢复。你希望我创建一个 /health 端点吗?”

如果用户同意,请为对应框架创建一个最精简的健康检查端点:

TanStack Start(src/routes/health.tsx):

import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/health")({
  server: {
    handlers: {
      GET: async () => {
        return Response.json({ status: "ok" });
      },
    },
  },
});

Express/Node.js:

app.get('/health', (req, res) => {
  res.json({ status: 'ok' });
});

Next.js(app/health/route.ts 或 pages/api/health.ts):

export async function GET() {
  return Response.json({ status: 'ok' });
}

FastAPI:

@app.get("/health")
def health():
    return {"status": "ok"}

Go(net/http):

http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.Write([]byte(`{"status":"ok"}`))
})
健康检查最佳实践
  • 快速返回(基本健康检查中避免查询数据库)
  • 健康时返回 HTTP 200,不健康时返回非 200 状态码
  • 响应内容保持精简:{"status": "ok"} 即可
  • 使用统一路径:惯例是 /health

决策流程

除非缺少关键值,否则使用默认值。仅在必要时询问用户。

  • 健康检查端点:仅当找不到现有健康检查路由时才询问。
  • 启动命令:使用现有的 scripts.start 或框架默认值。如果没有明确的入口点,则询问。
  • 端口:使用常见默认值(Node 为 3000,Python 为 8000),除非配置文件或环境变量指定了端口。
  • 包管理器:根据锁文件推断。如果不存在锁文件,Node 默认使用 npm,Python 默认使用 pip。

基础镜像版本

重要:始终检测本地运行时版本,以确保开发和生产环境一致。不要依赖训练数据中的版本号。

版本选择优先级:

  1. 项目配置文件(优先级最高)——.nvmrc、.node-version、engines.node、.python-version、go.mod、rust-toolchain.toml、.ruby-version 等。
  2. 本地安装的版本——运行相应运行时的版本命令
  3. 回退到 references/base-images.md——仅在以上方法都失败时使用

请参阅 references/base-images.md,了解完整的版本检测指南、配置文件位置、版本到标签的映射,以及当前建议的回退版本。

默认使用 slim 变体;需要更小的镜像时使用 alpine(但可能存在兼容性取舍)。始终使用具体的主次版本标签,绝不使用 latest。

Dockerfile 最佳实践

通用原则
  • 使用具体的版本标签,而不是 latest(参见上文“基础镜像版本”)
  • 合并 RUN 命令以尽量减少镜像层
  • 按照指令变更频率从低到高排序
  • 使用 .dockerignore 排除不必要的文件
  • 在生产环境中以非 root 用户运行
  • 添加 EXPOSE 以供文档说明
多阶段构建模式
# Build stage (verify current LTS version in references/base-images.md)
FROM node:24-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN npm run build

# Production stage
FROM node:24-slim AS runner
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -u 1001 -S appuser -G appgroup
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
框架特定注意事项

TanStack Start:详细说明请参阅 references/tanstack-start.md。要点:

  • package.json 中需要 "type": "module"
  • 需要包含 tanstackStart() 和 nitro() 插件的 vite.config.ts
  • 构建输出位于 .output/server/index.mjs
  • 使用 Node 24 slim,并通过 corepack 使用 pnpm
  • 添加 /health 路由用于健康检查

Next.js:使用 standalone 输出模式,复制 .next/standalone 和 .next/static

Vite/React:构建静态文件,并使用 nginx 或 Node 服务提供

Python/FastAPI:使用 slim 镜像,通过 --no-cache-dir 安装

Go:构建静态二进制文件,使用 scratch 或 distroless 镜像来精简镜像

输出格式

创建 Dockerfile 后,按以下顺序提供输出:

  1. 完整的 Dockerfile
  2. 如果不存在 .dockerignore 文件,则提供一个
  3. 在本地构建和测试的说明:
    docker build -t myapp .
    docker run -p 3000:3000 myapp
    
  4. 如果不存在 haloy.yaml,请告知用户:

    "要完成 haloy 设置,你需要一个 haloy.yaml 配置文件。你可以运行 /haloy-config 技能来生成该文件,也可以查看 haloy 文档了解配置选项。"

参考文件

阅读相应的参考文件以了解详细说明:

  • 基础镜像:references/base-images.md——所有运行时当前建议的版本(请先查看此文件!)
  • TanStack Start:references/tanstack-start.md——完整指南,包含健康检查、数据库设置和 haloy.yaml 示例

何时创建 .dockerignore

始终检查是否已有 .dockerignore。如果没有,请根据项目类型创建一个。常见的排除项:

node_modules
.git
.env
.env.*
*.log
dist
.next
.output
.vinxi
__pycache__
*.pyc
.venv
target
haloy.yaml

重要:始终将 haloy.yaml 添加到 .dockerignore 中。haloy 使用此文件进行部署配置,但容器内不需要它。排除该文件可改善 Docker 层缓存,因为对 haloy.yaml 的更改(例如更新域名或环境变量)不会使构建缓存失效。

评论

支持 Markdown