gongxiangp2/Dockerfile
chenpei 4712175cb0 feat(素材链路): 发布白底图双轨与AI生图回传能力
- 完成白底图 WebP 双轨接口、上传链路与预览缓存改造
- 新增 AI 生图平台成品回传接口、任务状态与表单规则
- 补齐 AI 生成标签、任务详情补全、相关测试与对接文档
2026-03-25 10:28:02 +08:00

112 lines
4.4 KiB
Docker
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.

# 基础镜像(使用 Alpine,手动处理 OpenSSL 兼容性)
ARG BASE_IMAGE=node:18-alpine
ARG ALPINE_MIRROR=https://mirrors.aliyun.com/alpine
FROM ${BASE_IMAGE} AS base
# 安装依赖阶段
FROM base AS deps
ARG ALPINE_MIRROR
RUN sed -i "s|https://dl-cdn.alpinelinux.org/alpine|${ALPINE_MIRROR}|g" /etc/apk/repositories && \
apk add --no-cache libc6-compat python3 make g++ cairo-dev jpeg-dev pango-dev giflib-dev
WORKDIR /app
# 复制 package.json(利用 Docker 层缓存)
COPY package.json package-lock.json* ./
# canvas 在项目里是可选依赖,且服务端代码已做降级处理。
# 构建机当前卡在 canvas 的 node-pre-gyp 安装阶段,因此这里只在镜像构建时跳过它。
RUN node -e "const fs=require('fs'); const pkg=require('./package.json'); if (pkg.optionalDependencies && pkg.optionalDependencies.canvas) { delete pkg.optionalDependencies.canvas; fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\\n'); }"
# 安装依赖(使用淘宝镜像 + BuildKit缓存)
RUN --mount=type=cache,target=/root/.npm \
echo "Installing dependencies (using cache if available)..." && \
npm config set registry https://registry.npmmirror.com && \
npm install --prefer-offline --no-audit --no-fund --legacy-peer-deps && \
echo "Dependencies installed ($(du -sh /app/node_modules | cut -f1))"
# 构建阶段
FROM base AS builder
ARG ALPINE_MIRROR
# 安装构建依赖
RUN sed -i "s|https://dl-cdn.alpinelinux.org/alpine|${ALPINE_MIRROR}|g" /etc/apk/repositories && \
apk add --no-cache libc6-compat python3 make g++ cairo-dev jpeg-dev pango-dev giflib-dev ffmpeg openssl
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# 设置环境变量
ENV NEXT_TELEMETRY_DISABLED=1
# 构建时使用假的环境变量(只用于构建,运行时会被容器的真实环境变量覆盖)
# 这样 Prisma 和其他模块在构建时不会报错
ENV DATABASE_URL="postgresql://build:build@localhost:5432/build"
ENV NEXTAUTH_SECRET="build-time-secret"
ENV NEXTAUTH_URL="http://localhost:3000"
ENV ADMIN_API_KEY="build-time-key"
ENV DINGTALK_CLIENT_ID="build-time-dingtalk-id"
ENV DINGTALK_CLIENT_SECRET="build-time-dingtalk-secret"
# 构建应用(复用 Next.js 构建缓存)
RUN --mount=type=cache,target=/app/.next/cache \
NODE_ENV=production npm run build
# 清理 standalone 目录中不需要的文件(减少 1GB+ 体积)
RUN echo "清理 standalone 目录..." && \
rm -rf .next/standalone/uploads && \
rm -rf .next/standalone/.build-cache && \
rm -rf .next/standalone/.docker-cache && \
rm -rf .next/standalone/.git && \
rm -rf .next/standalone/__tests__ && \
rm -rf .next/standalone/docs && \
rm -rf .next/standalone/backups && \
rm -rf .next/standalone/.kiro && \
rm -rf .next/standalone/scripts && \
echo "清理完成"
# 生产运行阶段
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ARG ALPINE_MIRROR
RUN sed -i "s|https://dl-cdn.alpinelinux.org/alpine|${ALPINE_MIRROR}|g" /etc/apk/repositories && \
apk add --no-cache ffmpeg python3 cairo jpeg pango giflib openssl poppler-utils
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# 复制必要文件
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/app ./app
# 只复制运行时必需的 node_modules
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/ag-psd ./node_modules/ag-psd
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/ioredis ./node_modules/ioredis
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@ioredis ./node_modules/@ioredis
# 只复制 schema.prisma,不复制 migrations 和 engine-cache(减少 35MB)
COPY --from=builder --chown=nextjs:nodejs /app/prisma/schema.prisma ./prisma/schema.prisma
COPY --from=builder --chown=nextjs:nodejs /app/lib ./lib
# 创建必要目录并设置权限
RUN mkdir -p /app/public /app/uploads && \
mkdir -p /app/uploads/temp && \
mkdir -p /app/uploads/assembled && \
mkdir -p /app/uploads/materials && \
mkdir -p /app/uploads/cleanup && \
chown -R nextjs:nodejs /app/public /app/uploads && \
chmod -R 777 /app/uploads
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]