全项目扫描修复: Docker数据卷修复+安全requireAdmin+12页SEO+API白名单+脚本超时+常量提取+假数据删除
This commit is contained in:
+104
@@ -0,0 +1,104 @@
|
||||
# =============================================================================
|
||||
# 追光AI 项目 Dockerfile (多阶段构建)
|
||||
# - stage 1 deps : 安装全部依赖 (含 dev)
|
||||
# - stage 2 builder : 跑 next build + prisma generate
|
||||
# - stage 3 runner : 仅拷贝运行所需,最小化镜像
|
||||
# - 一个镜像两种身份:APP 启动 nextjs / CRON 启动 supercronic(docker-compose 决定)
|
||||
# =============================================================================
|
||||
|
||||
# ---- 阶段 1: 安装依赖 ----
|
||||
FROM node:20-alpine AS deps
|
||||
WORKDIR /app
|
||||
|
||||
# 装 python + make + g++ 给 mysql2 / bcryptjs 等原生模块编译用
|
||||
# 先切换到 aliyun apk 镜像(默认源在中国大陆极慢,1m+ vs 0.1s)
|
||||
RUN sed -i 's|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g' /etc/apk/repositories \
|
||||
&& apk add --no-cache python3 make g++ openssl
|
||||
|
||||
# 先 copy lock file 缓存层
|
||||
COPY package.json package-lock.json ./
|
||||
COPY prisma ./prisma
|
||||
|
||||
# 用 ci 安装保证版本一致(同时切到 npmmirror 加速)
|
||||
RUN npm config set registry https://registry.npmmirror.com \
|
||||
&& npm ci --no-audit --no-fund --include=dev
|
||||
|
||||
# ---- 阶段 2: 构建 ----
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
RUN sed -i 's|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g' /etc/apk/repositories \
|
||||
&& apk add --no-cache python3 make g++ openssl
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
ENV NODE_ENV=production
|
||||
ENV npm_config_registry=https://registry.npmmirror.com
|
||||
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
# 跑 next build 生成 .next/
|
||||
# DATABASE_URL 在 build 时不需要(next 是 SSG/SSR-on-demand),但 prisma generate 需要
|
||||
# 用 .env.example 当 placeholder 生成 prisma client
|
||||
# 同时注入 OPENAI_API_KEY / DEEPSEEK_API_KEY 占位值,避免 openai SDK v6+ 构造时抛错
|
||||
# (build 期不会真正调用 AI,仅为通过模块求值)
|
||||
RUN if [ ! -f .env ]; then cp .env.example .env 2>/dev/null || echo "DATABASE_URL=placeholder" > .env; fi \
|
||||
&& export DEEPSEEK_API_KEY="${DEEPSEEK_API_KEY:-sk-build-placeholder}" \
|
||||
&& export OPENAI_API_KEY="${OPENAI_API_KEY:-sk-build-placeholder}" \
|
||||
&& npx prisma generate \
|
||||
&& DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" OPENAI_API_KEY="$OPENAI_API_KEY" npm run build
|
||||
|
||||
# ---- 阶段 3: 运行 ----
|
||||
FROM node:20-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# runtime 基础包
|
||||
RUN apk add --no-cache openssl tini curl bash
|
||||
# supercronic 用于 cron 容器调度(架构:alpine musl 兼容)
|
||||
# 直接 COPY 本地预下载的二进制(避免 Docker build 阶段从 GitHub 下载超时)
|
||||
# 下载源: https://github.com/aptible/supercronic/releases/tag/v0.2.33
|
||||
# SHA1: 71b0d58cc53f6bd72cf2f293e09e294b79c666d8
|
||||
ARG SUPERCRONIC=supercronic-linux-amd64
|
||||
COPY --chown=root:root scripts/bin/${SUPERCRONIC} /usr/local/bin/${SUPERCRONIC}
|
||||
RUN chmod +x /usr/local/bin/${SUPERCRONIC}
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
ENV PORT=8301
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
|
||||
# 非 root 运行
|
||||
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
|
||||
|
||||
# 拷贝必要文件
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
COPY --from=builder /app/scripts ./scripts
|
||||
# seed data files for volume auto-fill
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/data ./data-seed
|
||||
# 配置/类型文件(必须存在;如果不存在 COPY 会失败但构建继续)
|
||||
COPY --from=builder /app/next.config.mjs ./next.config.mjs
|
||||
COPY --from=builder /app/postcss.config.mjs ./postcss.config.mjs
|
||||
COPY --from=builder /app/tsconfig.json ./tsconfig.json
|
||||
COPY --from=builder /app/components.json ./components.json
|
||||
|
||||
# entrypoint 脚本
|
||||
COPY --chown=root:root scripts/entrypoint-app.sh /usr/local/bin/entrypoint-app.sh
|
||||
COPY --chown=root:root scripts/entrypoint-cron.sh /usr/local/bin/entrypoint-cron.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint-app.sh /usr/local/bin/entrypoint-cron.sh
|
||||
|
||||
# 数据 / 日志目录交给 nextjs
|
||||
RUN mkdir -p /app/data /app/public/bot-avatars /app/logs && chown -R nextjs:nodejs /app/data /app/public /app/logs
|
||||
|
||||
# 健康检查 (用 curl 探活)
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD curl -fs http://localhost:8301/api/health || exit 1
|
||||
|
||||
# 默认是 app 身份,cron 容器在 compose 里 override command
|
||||
USER nextjs
|
||||
EXPOSE 8301
|
||||
|
||||
ENTRYPOINT ["/sbin/tini", "--"]
|
||||
CMD ["/usr/local/bin/entrypoint-app.sh"]
|
||||
Reference in New Issue
Block a user