Files
OJ2/.dockerignore
yuetsh f00c941ede
Some checks failed
Deploy / deploy (push) Has been cancelled
perf(构建): builder 分开拷源码,只改后端不再陪编一次前端
builder 阶段是 `COPY . .` 一把梭,而 docker 的层缓存是链式的:那一层的校验和
覆盖整个仓库,改任何一个文件都会把它作废,后面 vite build 和 bun compile 全部
重跑。前端那 160s 一次都躲不掉,改一篇 markdown 也要陪着编。

按各自的输入分开拷,慢的那条放前面(缓存链上越靠前越不容易被碰到):

  只改 apps/api           前端两层命中缓存,只重编后端       ~1s
  只改 apps/web           前端重编,后端被链条带着            ~160s
  改 packages/contract    两边都重编(本来就都依赖它,是对的)
  改 docs / 根上的杂项    builder 根本看不见                  0

代价是 builder 只看得见这里点名拷进来的四样,新加顶层目录要同步加 COPY。

顺带堵掉两个同源的洞:

· apps/web/docs、tests、**/CLAUDE.md 进了 .dockerignore。它们在 apps/web 里面,
  整个目录拷进去的话,改一篇文档也会让 vite build 那层失效。

· .dockerignore 末尾为 --prebuilt 开的例外(!dist/oj2-api、!apps/web/dist)让本地
  产物照样进构建上下文 —— 这是比 `COPY . .` 更隐蔽的一条:在本机编一次后端,
  80MB 的 dist/oj2-api 变了,rsync 上去,服务器就重编一次前端,源码一行没动。
  dist/oj2-api 现在不再被 builder 拷贝;apps/web/dist 仍在 COPY apps/web 里面,
  所以 deploy.sh 头上那条手动 rsync 补了 --exclude dist。CI 走 --prebuilt,
  builder 整个不进构建图,不受影响。

验证:用老 Dockerfile 和新 Dockerfile 各构建一次 --target artifacts 导出对比,
后端二进制 sha256 相同,前端 dist 500 个文件逐个 sha256 一致。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 10:25:15 -06:00

54 lines
1.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 构建上下文是仓库根,这里把不该进去的挡掉。
#
# data/ 尤其重要:测试用例和上传文件可以有几十 GB而且 judge_server/run 下
# 是判题沙箱以别的 uid 建的目录docker 连 stat 都做不了,不排除的话构建直接失败。
data/
dist/
node_modules/
**/node_modules/
.git/
.github/
# 本地产物与缓存
**/dist/
**/.vite/
**/*.log
# 密钥绝不进镜像层
.env
.env.*
docker/.env
docker/.env.*
!.env.example
!docker/.env.example
# 前端 dist 由构建阶段自己生成,本地那份不要带进去污染
apps/web/dist/
# apps/ 下的非构建输入。Dockerfile 里是整个目录拷进去的(`COPY apps/web apps/web`
# 所以改一篇 docs/ 里的 markdown 也会让 `RUN vite build` 那层失效,白编 160s。
# 这几样都不被源码 import挡在上下文外面最省事。
apps/web/docs/
apps/web/tests/
**/CLAUDE.md
**/README.md
# —— 例外ARTIFACTS=prebuilt 时,产物本身就是构建输入 ——
#
# 这几条必须放在文件最后dockerignore 是**最后一条匹配的规则说了算**
# 写在上面那些 dist 规则前面等于没写。
#
# ARTIFACTS=build默认服务器手动部署走的那条时它们只是让上下文多传
# 几十 MB镜像里用不到本地根本没编过的话这两个路径不存在也不影响。
#
# ⚠️ 一个代价:`apps/web/dist` 因此会进 builder 的 `COPY apps/web` 那一层,
# 也就进了它的缓存键 —— 手边有一份内容不同的本地 dist就会白重编一次前端。
# 所以 docker/deploy.sh 头上那条手动 rsync 用 --exclude dist 把它挡在服务器外。
# CI 走 --prebuiltbuilder 整个不进构建图,不受这条影响。)
!dist/oj2-api
!apps/web/dist
!apps/web/dist/**