50 lines
2.0 KiB
Docker
50 lines
2.0 KiB
Docker
# ---- 基础镜像:Alpine 轻量基础 + pnpm 全局安装 ----
|
||
FROM node:24-alpine AS base
|
||
# 替换为阿里云镜像源,加速 apk 安装
|
||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
|
||
apk add --no-cache libc6-compat
|
||
# pnpm 使用阿里云镜像源
|
||
RUN npm config set registry https://registry.npmmirror.com/ && \
|
||
npm install -g pnpm && \
|
||
pnpm config set registry https://registry.npmmirror.com/
|
||
WORKDIR /app
|
||
|
||
# ---- 依赖安装层:独立分层,依赖不变时命中缓存 ----
|
||
FROM base AS deps
|
||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||
# 挂载 pnpm store 缓存,避免重复下载依赖包
|
||
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store \
|
||
pnpm install --frozen-lockfile --prefer-offline
|
||
|
||
# ---- 构建层:生成 Prisma Client + Next.js 产物 ----
|
||
FROM base AS builder
|
||
ENV NEXT_TELEMETRY_DISABLED=1 NODE_ENV=production
|
||
# 构建时仅需 DATABASE_URL(db:generate 生成 Drizzle Client)
|
||
ARG DATABASE_URL
|
||
ENV DATABASE_URL=${DATABASE_URL}
|
||
|
||
# 从 deps 层复制已安装的 node_modules,避免重复安装
|
||
COPY --from=deps /app/node_modules ./node_modules
|
||
COPY . .
|
||
# 挂载 .next/cache 缓存,加速增量构建(webpack/turbopack 缓存复用)
|
||
RUN --mount=type=cache,id=next-cache,target=/app/.next/cache \
|
||
pnpm db:generate && pnpm build
|
||
|
||
# ---- 运行层:仅包含 standalone 产物,最小化镜像体积 ----
|
||
FROM node:24-alpine AS runner
|
||
WORKDIR /app
|
||
|
||
ENV NODE_ENV=production NEXT_TELEMETRY_DISABLED=1 PORT=3000 HOSTNAME="0.0.0.0"
|
||
|
||
# 非 root 用户运行,提升安全性
|
||
RUN addgroup --system --gid 1001 nodejs && \
|
||
adduser --system --uid 1001 nextjs
|
||
|
||
# 仅复制 standalone 产物 + 静态资源,不携带 node_modules 和源码
|
||
COPY --from=builder /app/public ./public
|
||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||
|
||
USER nextjs
|
||
EXPOSE 3000
|
||
CMD ["node", "server.js"] |