Ctrl K
ComunidadGuías…

server/Dockerfile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# ===== 构建阶段:编译 TS + 编译 better-sqlite3 原生模块 =====
# 版本策略:node:22-alpine 是官方维护的 LTS 滚动标签(含安全补丁)。
# 想要完全可复现的镜像,把基础镜像钉到具体小版本或 digest 即可。
FROM node:22-alpine AS builder

# better-sqlite3 等原生依赖编译链(只在构建层存在,不进最终镜像)
RUN apk add --no-cache python3 make g++

WORKDIR /app

# npm ci:严格按 package-lock.json 装(此前用 npm install + 可选 glob,
# 结果镜像内容取决于构建日期——express/better-sqlite3 的 ^ 版本会漂移)
COPY package.json package-lock.json ./
RUN npm ci

COPY tsconfig.json ./
COPY src ./src
RUN npm run build

# 生产依赖剪枝后整体搬到运行层,避免在最终镜像里重新编译一遍原生模块
RUN npm prune --omit=dev

# ===== 运行阶段:仅携带产物与生产依赖 =====
FROM node:22-alpine AS runtime

# tini 处理信号(SQLite WAL 需要优雅退出);不再需要 python3/make/g++
RUN apk add --no-cache tini

WORKDIR /app
ENV NODE_ENV=production

COPY package.json package-lock.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist

# 数据目录(compose 挂载卷持久化)
# 注意:这里保持以 root 运行。改成 USER node 会让「已在跑的实例」升级后写不进
# 原来 root 属主的 data/ 目录(NAS 上表现为服务直接起不来);要收紧的话请连同
# DEPLOY_*.md 里的 chown -R 1000:1000 data 一次性迁移步骤一起改。
RUN mkdir -p /app/data
ENV DATA_DIR=/app/data

EXPOSE 8420

# 镜像自带健康检查(此前只有 docker-compose 配了 healthcheck,
# 直接用 docker run / 群晖容器界面跑就没有任何存活探测)
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
  CMD node -e "const p=process.env.PORT||8420;fetch('http://127.0.0.1:'+p+'/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "dist/index.js"]