62 lines
3.0 KiB
Docker
62 lines
3.0 KiB
Docker
# syntax=docker/dockerfile:1
|
||
|
||
# ===== 前端构建:Nuxt generate 产出静态站点 =====
|
||
FROM node:22-bookworm-slim AS frontend-build
|
||
WORKDIR /build/frontend
|
||
COPY frontend/package.json frontend/package-lock.json ./
|
||
# lockfile 的 resolved 可能指向带鉴权的私有 registry(开发者本机 .npmrc),镜像内会 401。
|
||
# 构建期删除 resolved 字段(integrity 校验不受影响),让 npm 统一走公共 registry
|
||
RUN node -e "const fs=require('fs');const l=JSON.parse(fs.readFileSync('package-lock.json'));for(const p of Object.values(l.packages||{}))delete p.resolved;fs.writeFileSync('package-lock.json',JSON.stringify(l,null,2))" \
|
||
&& npm ci --no-audit --no-fund --registry=https://registry.npmjs.org
|
||
COPY frontend/ ./
|
||
RUN npm run generate
|
||
|
||
# ===== 后端构建:安装依赖(含原生模块编译) =====
|
||
FROM node:22-bookworm AS backend-build
|
||
WORKDIR /build/backend
|
||
COPY backend/package.json backend/package-lock.json ./
|
||
RUN node -e "const fs=require('fs');const l=JSON.parse(fs.readFileSync('package-lock.json'));for(const p of Object.values(l.packages||{}))delete p.resolved;fs.writeFileSync('package-lock.json',JSON.stringify(l,null,2))" \
|
||
&& npm ci --no-audit --no-fund --registry=https://registry.npmjs.org
|
||
COPY backend/ ./
|
||
# 运行时与既有服务器部署一致走 tsx(源码存在 bundler 风格无扩展名 import,tsc 产物 node 直跑不可行);
|
||
# tsx 是 devDependency,prune 后单独补装
|
||
RUN npm prune --omit=dev && npm i tsx@^4.21.0 --no-save --no-audit --no-fund --registry=https://registry.npmjs.org
|
||
|
||
# ===== 运行时 =====
|
||
FROM node:22-bookworm-slim
|
||
ARG HUOBAO_VERSION=dev
|
||
ENV NODE_ENV=production \
|
||
HUOBAO_VERSION=${HUOBAO_VERSION} \
|
||
PORT=5679 \
|
||
FFMPEG_BIN=/usr/bin/ffmpeg \
|
||
FFPROBE_BIN=/usr/bin/ffprobe \
|
||
HUOBAO_DATA_DIR=/app/data \
|
||
SQLITE_PATH=/app/data/huobao.sqlite3 \
|
||
WORKSPACE_PATH=/app/data/workspace \
|
||
FRONTEND_DIST=/app/frontend-dist
|
||
|
||
# ffprobe-static 不包含 Linux ARM64 二进制;两个架构统一使用系统媒体工具。
|
||
RUN apt-get update \
|
||
&& apt-get install -y --no-install-recommends ffmpeg \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
WORKDIR /app
|
||
COPY --from=backend-build /build/backend/src ./backend/src
|
||
COPY --from=backend-build /build/backend/node_modules ./backend/node_modules
|
||
COPY --from=backend-build /build/backend/package.json ./backend/package.json
|
||
COPY --from=backend-build /build/backend/tsconfig.json ./backend/tsconfig.json
|
||
# workspace 模板(skills/prompts),entrypoint copy-once 到数据卷后可在线编辑
|
||
COPY backend/workspace ./workspace-template
|
||
COPY --from=frontend-build /build/frontend/.output/public ./frontend-dist
|
||
COPY docker/entrypoint.sh ./entrypoint.sh
|
||
RUN chmod +x ./entrypoint.sh && mkdir -p /app/data
|
||
|
||
# 数据卷:SQLite + 生成的静态文件 + 可编辑 workspace
|
||
VOLUME ["/app/data"]
|
||
EXPOSE 5679
|
||
|
||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s \
|
||
CMD node -e "fetch('http://localhost:'+(process.env.PORT||5679)+'/api/v1/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
||
|
||
ENTRYPOINT ["./entrypoint.sh"]
|