Skip to content

feat: add Dockerfile for containerized deployment#54

Merged
Svtter merged 4 commits into
mainfrom
worktree-add-dockerfile
May 15, 2026
Merged

feat: add Dockerfile for containerized deployment#54
Svtter merged 4 commits into
mainfrom
worktree-add-dockerfile

Conversation

@Svtter
Copy link
Copy Markdown
Contributor

@Svtter Svtter commented May 15, 2026

Summary

  • Add multi-stage Dockerfile using golang:1.24-alpine (build) and alpine:3.21 (runtime)
  • Enable CGO for go-sqlite3 dependency
  • Add .dockerignore to exclude unnecessary files from build context
  • Verified: image builds and runs successfully

Usage

docker build -t static-html .
docker run --rm -p 3939:3939 static-html start --host 0.0.0.0 --port 3939

Test plan

  • Docker build succeeds
  • Container starts and --help output is correct

🤖 Generated with Claude Code

Multi-stage build using golang:1.24-alpine for building and
alpine:3.21 for the runtime image. Includes CGO support for
go-sqlite3 dependency.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

可合并

总结

Dockerfile 采用多阶段构建,使用了层缓存优化,整体设计合理。但存在端口标注不准确的问题。

阻塞项:无

建议项

  1. EXPOSE 8080 与实际端口不一致:应用默认端口为 3939(见 internal/server/server.go:27),EXPOSE 8080 会给用户造成误导。虽然 docker run -p 可以覆盖,但建议改为 EXPOSE 3939(或用构建参数/CMD 传递端口)。

  2. .dockerignore 缺少 .git 目录.git 体积较大且对构建无用,建议添加以减少构建上下文大小和传输时间。

  3. 容器以 root 运行:可考虑添加非 root 用户(如 USER 1000:1000),降低容器逃逸风险。

  4. 缺少 HEALTHCHECK:可添加健康检查指令,方便容器编排工具感知服务状态。

  5. .dockerignore 中的 LICENSE 建议保留:若容器中需要保留许可证信息,不应过滤;若确实不需要,建议用更具体模式如 /LICENSE 避免误过滤其他路径下的同名文件。

New%20session%20-%202026-05-15T06%3A09%3A54.068Z
opencode session  |  github run

@github-actions
Copy link
Copy Markdown

基于 PR 标题/正文的规格与实现对比,分析结果如下:

发现遗漏

在 PR 正文的使用说明及应用实际默认端口(internal/server/server.go:27DefaultPort = 3939)均指向 3939 端口,但 Dockerfile:23EXPOSE 8080 为错误端口号,与规格及应用默认端口不符。

MEDIUM

  • EXPOSE 端口号与规格/应用默认值不一致
    • 规格:使用说明中 docker run --rm -p 3939:3939 表明容器监听 3939。
    • 实现:Dockerfile:23 中为 EXPOSE 8080,应改为 EXPOSE 3939
    • EXPOSE 虽仅是文档性声明,但错误值会误导使用者相信容器在 8080 端口提供服务,而实际服务运行在 3939。
    • 修改位置:Dockerfile 第 23 行,将 EXPOSE 8080 改为 EXPOSE 3939

LOW

  • .dockerignore 未排除 .git 目录
    • 规格要求:"排除构建上下文中不需要的文件"。.git 目录体积较大,若不排除会导致构建上下文膨胀、build 变慢。
    • 修改位置:.dockerignore 中添加 .git 条目。

New%20session%20-%202026-05-15T06%3A09%3A54.110Z
opencode session  |  github run

- Change EXPOSE from 8080 to 3939 (matches app default port)
- Add non-root user (appuser) for security
- Add .git to .dockerignore to reduce build context
- Use /LICENSE instead of LICENSE to avoid over-matching

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

现读取实现文件并与规格对比:

规格(来自 PR 标题+正文):

  1. 多阶段 Dockerfile,构建阶段 golang:1.24-alpine,运行阶段 alpine:3.21
  2. 启用 CGO 以支持 go-sqlite3
  3. 添加 .dockerignore 排除不需要的文件
  4. 镜像可构建、可运行(用法示例:docker run -p 3939:3939 ... --port 3939

实现对照:

规格项 实现 状态
多阶段 + 正确基础镜像 golang:1.24-alpine / alpine:3.21
启用 CGO CGO_ENABLED=1 + 安装 gcc musl-dev
.dockerignore 排除无关文件 已排除 .gitnode_modulesdistfixtures 等 7 项
镜像可构建运行 ENTRYPOINT + 用户使用 start --host 0.0.0.0 --port 3939
EXPOSE 端口与应用一致 EXPOSE 3939,与用法示例 -p 3939:3939 一致
非 root 运行 adduser -D -u 1000 appuser + USER appuser ✅(超出规格)

无遗漏

规格中的所有特性均已完整实现:多阶段构建、指定基础镜像版本、CGO 启用、.dockerignore 排除无关文件、构建产物正确拷贝至运行阶段、EXPOSE 端口与应用默认端口(3939)一致、设 ENTRYPOINT 确保启动命令正确。额外考虑了非 root 用户运行的安全性改进。

New%20session%20-%202026-05-15T06%3A12%3A57.782Z
opencode session  |  github run

@github-actions
Copy link
Copy Markdown

可合并

当前版本的 Dockerfile 和 .dockerignore 质量良好,上一轮审查指出的问题(EXPOSE 端口号、非 root 用户、.git 未排除等)已全部修复。

阻塞项:无

建议项

  1. RUN go mod download 未利用构建缓存:可使用 --mount=type=cache 挂载 Go module 缓存,后续重复构建时可复用已下载的依赖,减少网络耗时。
  2. 缺少 HEALTHCHECK 指令:添加健康检查可让容器编排工具(如 Docker Compose、K8s)感知服务存活状态,非强制但推荐。
  3. *.md 范围过宽*.md 会排除所有层级的 Markdown 文件(包括子目录中可能存在的文档)。若只想排除根目录的 README 文件,可改用更精确的 /*.md/README*.md,避免误过滤。
  4. 建议使用 COPY --link:在 Dockerfile 的 COPY 指令中使用 --link 可将文件复制与后续 RUN 解耦,利用 BuildKit 的独立层缓存,提升后续构建速度。

New%20session%20-%202026-05-15T06%3A13%3A00.011Z
opencode session  |  github run

- Add HEALTHCHECK directive for container orchestration awareness
- Change *.md to /*.md to avoid filtering markdown files in subdirectories

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

无遗漏

规格中的所有特性均已完整实现:

  • 多阶段构建:使用 golang:1.24-alpine(构建)和 alpine:3.21(运行),与规格一致
  • 启用 CGOCGO_ENABLED=1 + 安装 gcc musl-dev,与规格一致
  • .dockerignore:排除了 .gitnode_modulesdistfixtures.claude/*.md/LICENSE,覆盖规格要求的"排除不必要文件"
  • EXPOSE 3939:与用法示例 -p 3939:3939 一致
  • ENTRYPOINT 设为 html-server,确保容器能按预期启动
  • 额外改进:非 root 用户、HEALTHCHECKca-certificatesldflags 瘦身等均超出规格要求,无缺失项

New%20session%20-%202026-05-15T06%3A18%3A50.764Z
opencode session  |  github run

@github-actions
Copy link
Copy Markdown

可合并

总结

当前版本(最新 HEAD)已修复之前审查中提出的全部问题,包括 EXPOSE 端口改为 3939、添加非 root 用户、排除 .git、增加 HEALTHCHECK 等。Dockerfile 整体质量良好,遵循了安全最佳实践和层缓存优化。

阻塞项:无

建议项

  1. 缺少 CMD 指令ENTRYPOINT ["html-server"] 单独使用时,运行 docker run static-html(不带额外参数)会直接启动 html-server 而缺少 start 子命令,可能输出帮助信息而非运行服务。建议添加 CMD ["start"]CMD ["help"] 以改善默认行为。

  2. RUN go mod download 未利用缓存挂载:使用 --mount=type=cache,target=/go/pkg/mod 可让后续构建复用已下载的依赖模块,减少重复构建的网络耗时和构建时间。

  3. 构建阶段未指定 --mount=type=cachego build:同理,go build 可通过 --mount=type=cache,target=/root/.cache/go-build 加速后续构建。

  4. .dockerignorefixtures 排除:确认此目录仅用于测试数据(非运行必需),排除合理;但建议用路径前缀 /fixtures 避免误匹配同名子目录。

  5. 建议使用 COPY --link:可将 COPY 文件操作与后续依赖安装解耦,利用 BuildKit 独立层缓存提升构建效率。

New%20session%20-%202026-05-15T06%3A18%3A44.975Z
opencode session  |  github run

- Add CMD ["start", "--host", "0.0.0.0", "--port", "3939"] so docker run
  without args starts the server by default
- Change fixtures to /fixtures to avoid matching subdirectories

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

无遗漏

PR 标题/正文中明确列出的所有规格需求均已完整实现:

规格要求 实现情况
多阶段构建:golang:1.24-alpine (构建) + alpine:3.21 (运行) ✅ Dockerfile 第 2 行和第 15 行
启用 CGO 支持 go-sqlite3 CGO_ENABLED=1 + 安装 gcc musl-dev (第 4,12 行)
添加 .dockerignore 排除不必要文件 ✅ 已排除 .git, node_modules, dist, /fixtures, .claude, /*.md, /LICENSE
镜像可构建并正确运行(用法示例:-p 3939:3939 --port 3939 EXPOSE 3939, ENTRYPOINT + CMD, 端口号与应用默认端口 (3939) 一致

此外实现还超出了规格要求,增加了非 root 用户、HEALTHCHECKca-certificates、二进制瘦身等改进,无任何缺失项。

New%20session%20-%202026-05-15T06%3A52%3A55.123Z
opencode session  |  github run

@github-actions
Copy link
Copy Markdown

可合并

总结

Dockerfile 和 .dockerignore 实现质量良好,已正确定义多阶段构建、启用 CGO、使用非 root 用户、EXPOSE 3939HEALTHCHECK、以及正确的 ENTRYPOINT + CMD。经过检查,start 命令、--host--port 参数均已确认存在且行为一致。

阻塞项:无

建议项

  1. go mod downloadgo build 缺少缓存挂载:可通过 --mount=type=cache,target=/go/pkg/mod--mount=type=cache,target=/root/.cache/go-build 利用 BuildKit 缓存加速重复构建。

  2. COPY --link 未使用:在 Dockerfile 的 COPY 指令中使用 --link 可将文件复制与后续层解耦,利用 BuildKit 独立层缓存提升构建效率。

  3. wget 依赖 busybox 提供:当前 alpine:3.21wget 由 busybox 提供,功能受限(不支持 HTTPS),但对 HEALTHCHECK 的本地 HTTP 请求足够。如果未来健康检查需要 HTTPS,需显式安装 wget 包。

New%20session%20-%202026-05-15T06%3A52%3A53.849Z
opencode session  |  github run

@Svtter Svtter merged commit 38cc036 into main May 15, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant