129 lines
3.5 KiB
Docker
129 lines
3.5 KiB
Docker
# 基础镜像
|
||
FROM node:18-alpine AS base
|
||
|
||
# 安装依赖阶段
|
||
FROM base AS deps
|
||
# 使用阿里云镜像源加速
|
||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||
# 安装基础依赖和 canvas 所需的系统库
|
||
RUN apk add --no-cache \
|
||
libc6-compat \
|
||
openssl3 \
|
||
openssl-dev \
|
||
cairo \
|
||
cairo-dev \
|
||
pango \
|
||
pango-dev \
|
||
jpeg-dev \
|
||
giflib-dev \
|
||
librsvg \
|
||
pixman-dev \
|
||
python3 \
|
||
make \
|
||
g++ \
|
||
pkgconfig \
|
||
vips-dev \
|
||
fftw-dev \
|
||
build-base
|
||
WORKDIR /app
|
||
|
||
# 复制依赖文件
|
||
COPY package.json package-lock.json* ./
|
||
|
||
# 智能缓存策略:
|
||
# 1. 如果存在 .build-cache/node_modules.tar.gz,直接解压使用(10-20秒)
|
||
# 2. 否则执行 npm ci 下载(60-90秒)
|
||
COPY .build-cache/node_modules.tar.gz* /tmp/
|
||
RUN --mount=type=cache,target=/root/.npm,id=npm-cache,sharing=locked \
|
||
if [ -f /tmp/node_modules.tar.gz ]; then \
|
||
echo "✅ 使用缓存的 node_modules(快速模式)" && \
|
||
tar -xzf /tmp/node_modules.tar.gz && \
|
||
chmod -R +x node_modules/.bin && \
|
||
mkdir -p node_modules/canvas && \
|
||
echo "🔧 重新安装 sharp(musl 版本)" && \
|
||
npm config set registry https://registry.npmmirror.com && \
|
||
npm install --os=linux --libc=musl --cpu=x64 --legacy-peer-deps sharp; \
|
||
else \
|
||
echo "⚠️ 缓存不存在,重新下载依赖(首次构建)" && \
|
||
npm config set registry https://registry.npmmirror.com && \
|
||
npm config set cache /root/.npm --global && \
|
||
npm ci --prefer-offline --no-audit --ignore-optional --legacy-peer-deps && \
|
||
mkdir -p node_modules/canvas && \
|
||
echo "🔧 安装 sharp(musl 版本)" && \
|
||
npm install --os=linux --libc=musl --cpu=x64 --legacy-peer-deps sharp; \
|
||
fi
|
||
|
||
# 构建阶段
|
||
FROM base AS builder
|
||
# 安装构建时需要的依赖(sharp需要)
|
||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||
RUN apk add --no-cache \
|
||
openssl3 \
|
||
openssl-dev \
|
||
vips-dev \
|
||
fftw-dev \
|
||
build-base \
|
||
python3 \
|
||
make \
|
||
g++
|
||
WORKDIR /app
|
||
COPY --from=deps /app/node_modules ./node_modules
|
||
COPY . .
|
||
|
||
# 生成 Prisma Client
|
||
RUN npx prisma generate
|
||
|
||
# 设置环境变量
|
||
ENV NEXT_TELEMETRY_DISABLED 1
|
||
|
||
# 构建应用
|
||
RUN npm run build
|
||
|
||
# 生产运行阶段
|
||
FROM base AS runner
|
||
WORKDIR /app
|
||
|
||
ENV NODE_ENV production
|
||
ENV NEXT_TELEMETRY_DISABLED 1
|
||
|
||
# 使用阿里云镜像源加速
|
||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||
# 安装运行时依赖(包括 canvas 所需的库、FFmpeg 和 Prisma 所需的 OpenSSL)
|
||
RUN apk add --no-cache \
|
||
openssl3 \
|
||
openssl-dev \
|
||
cairo \
|
||
pango \
|
||
jpeg \
|
||
giflib \
|
||
librsvg \
|
||
pixman \
|
||
ffmpeg \
|
||
vips
|
||
|
||
RUN addgroup --system --gid 1001 nodejs
|
||
RUN 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/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/prisma ./prisma
|
||
COPY --from=builder --chown=nextjs:nodejs /app/lib ./lib
|
||
|
||
# 创建必要目录并设置权限
|
||
RUN mkdir -p /app/public /app/uploads && \
|
||
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"]
|
||
|