feat: 增加 Docker 部署(Dockerfile + compose,端口 2229)

用多阶段构建把 Nuxt 静态产物交给 nginx 托管,对外暴露 2229 端口。
nginx 配置覆盖 SPA 路由回退与静态资源缓存策略,构建上下文用 .dockerignore 排除依赖与产物。
This commit is contained in:
toor
2026-10-21 14:38:50 +08:00
committed by trae-solo-agent
parent 7920c0bba2
commit 7049eb02a8
4 changed files with 130 additions and 4 deletions
+26
View File
@@ -0,0 +1,26 @@
# 依赖与构建产物,由镜像内的 pnpm install / pnpm build 重新生成
node_modules
**/node_modules
.nuxt
**/.nuxt
.output
**/.output
dist
**/dist
# 版本控制与 CI
.git
.gitignore
.github
# 本地环境变量
.env
.env.*
!.env.example
# 编辑器与工具
.idea
.vscode
*.log
.DS_Store
.trae-html-share-packages
+32 -4
View File
@@ -1,17 +1,45 @@
# ---------- 构建阶段 ----------
FROM node:24-alpine AS builder
RUN apk update
# pnpm 版本与 package.json 的 packageManager 字段保持一致
RUN npm install -g pnpm@11.21.0
WORKDIR /app
# 构建期关闭遥上报,避免容器构建时产生外部请求
ENV NUXT_TELEMETRY_DISABLED=1
# 先只复制依赖清单,让 pnpm install 这一层可以被缓存复用
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/web/package.json apps/web/package.json
COPY packages/cook/package.json packages/cook/package.json
COPY docs/package.json docs/package.json
RUN pnpm install --frozen-lockfile
# 再复制源码并构建
COPY . .
# Public analytics settings are compiled into the static site.
# 统计配置在构建期编译进静态产物
ARG NUXT_PUBLIC_CLARITY_PROJECT_ID=ks1ebw03i5
ARG NUXT_PUBLIC_CLARITY_DOMAINS=cook.yunyoujun.cn,cook.yunle.fun
ENV NUXT_PUBLIC_CLARITY_PROJECT_ID=${NUXT_PUBLIC_CLARITY_PROJECT_ID}
ENV NUXT_PUBLIC_CLARITY_DOMAINS=${NUXT_PUBLIC_CLARITY_DOMAINS}
RUN pnpm install --frozen-lockfile && pnpm run build
# 镜像里没有 .git,版本号组件拿不到 commit;传入该值即可显示版本信息
ARG CF_PAGES_COMMIT_SHA=
ENV CF_PAGES_COMMIT_SHA=${CF_PAGES_COMMIT_SHA}
# 构建产物输出到仓库根目录的 dist/(见 scripts/copy-web-output.ts)
RUN pnpm run build
# ---------- 运行阶段 ----------
FROM nginx:stable-alpine
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
EXPOSE 2229
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://127.0.0.1:2229/ >/dev/null || exit 1
+23
View File
@@ -0,0 +1,23 @@
services:
cook:
build:
context: .
dockerfile: Dockerfile
args:
# 统计配置在构建期编译进静态产物,未设置时使用项目默认值
NUXT_PUBLIC_CLARITY_PROJECT_ID: ${NUXT_PUBLIC_CLARITY_PROJECT_ID:-ks1ebw03i5}
NUXT_PUBLIC_CLARITY_DOMAINS: ${NUXT_PUBLIC_CLARITY_DOMAINS:-cook.yunyoujun.cn,cook.yunle.fun}
# 可选:传入 git commit,页脚会显示版本号与提交
CF_PAGES_COMMIT_SHA: ${CF_PAGES_COMMIT_SHA:-}
image: cook-web:latest
container_name: cook-web
restart: unless-stopped
ports:
# 容器内 nginx 监听 2229,对外同样暴露 2229
- '2229:2229'
healthcheck:
test: [CMD, wget, -q, -O, /dev/null, http://127.0.0.1:2229/]
interval: 30s
timeout: 3s
start_period: 5s
retries: 3
+49
View File
@@ -0,0 +1,49 @@
server {
listen 2229;
server_name _;
root /usr/share/nginx/html;
index index.html;
# 静态资源压缩
# 注意:显式声明 gzip_types 会覆盖内置默认列表,但 text/html 始终会被压缩,无需重复声明
#(重复写 text/html 只会触发 nginx 的 duplicate MIME type 警告)
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;
# 带内容哈希的构建产物可以长期缓存
location /_nuxt/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
# Service Worker 每次都要回源校验,否则老用户会被锁在旧版本
location = /sw.js {
add_header Cache-Control "no-cache, no-store, must-revalidate";
try_files $uri =404;
}
# 无扩展名的关联域名文件需要正确的 Content-Type
location /.well-known/ {
default_type application/json;
add_header Cache-Control "public, max-age=3600";
try_files $uri =404;
}
# CSR 应用:未预渲染的路由交给前端路由处理
location / {
try_files $uri $uri/ /index.html;
}
error_page 404 /404.html;
}