gongxiangp2/Dockerfile

138 lines
4.2 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.

# 基础镜像(支持通过构建参数覆盖)
ARG BASE_IMAGE=node:18-alpine
FROM ${BASE_IMAGE} 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* ./
# 智能缓存策略(优化以减少SSD写入):
# 1. 优先使用缓存挂载(cache mount),减少磁盘写入
# 2. 如果存在 .build-cache/node_modules.tar.gz,直接解压使用(10-20秒)
# 3. 否则执行 npm ci 下载(60-90秒)
# 使用缓存挂载存储 npm 缓存,避免写入到镜像层
COPY .build-cache/node_modules.tar.gz* /tmp/
RUN --mount=type=cache,target=/root/.npm,id=npm-cache,sharing=locked \
--mount=type=cache,target=/tmp/.npm-cache,id=npm-tmp-cache \
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 config set cache /root/.npm --global && \
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 --mount=type=cache,target=/root/.cache/prisma,id=prisma-cache \
npx prisma generate
# 设置环境变量
ENV NEXT_TELEMETRY_DISABLED 1
# 构建应用(使用缓存挂载存储 Next.js 缓存,减少磁盘写入)
RUN --mount=type=cache,target=/app/.next/cache,id=nextjs-cache \
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、PDF处理工具和 Prisma 所需的 OpenSSL)
RUN apk add --no-cache \
openssl3 \
openssl-dev \
cairo \
pango \
jpeg \
giflib \
librsvg \
pixman \
ffmpeg \
vips \
poppler-utils
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/app ./app
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"]