furniture-3d-system-Wu/Dockerfile.optimized
WuYongJie 9859afc4aa 初始化3D家具展示系统项目
- 完整的Next.js 14 + TypeScript项目架构
- 集成Three.js和GSAP用于3D渲染和动画
- Prisma ORM + PostgreSQL数据库
- Docker容器化部署支持
- 本地缓存优化系统
- 中文界面和注释
- 移动端响应式设计
- 健康检查和监控功能
2025-12-11 16:42:59 +08:00

192 lines
5.9 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.

# ============================================
# 3D家具安装展示系统 - 优化版Dockerfile
# 优先使用本地缓存,支持离线构建
# ============================================
# ============================================
# 阶段 1: 基础镜像
# ============================================
FROM node:18-alpine AS base
# 使用阿里云镜像源加速(中国网络优化)
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 安装基础运行时依赖
RUN apk add --no-cache \
libc6-compat \
ca-certificates \
openssl3
# ============================================
# 阶段 2: 依赖安装 (deps)
# ============================================
FROM base AS deps
# 安装构建时依赖
RUN apk add --no-cache --virtual .build-deps \
python3 \
make \
g++ \
pkgconfig \
openssl-dev
WORKDIR /app
# 复制package文件
COPY package.json package-lock.json* ./
# 检查是否有本地缓存的node_modules
COPY cache/node_modules* ./cache_node_modules/ 2>/dev/null || true
# 配置npm使用国内镜像源
RUN npm config set registry https://registry.npmmirror.com/
# 智能安装依赖:优先使用缓存,然后网络安装
RUN set -ex && \
# 如果有本地缓存,先复制关键包
if [ -d "./cache_node_modules" ]; then \
echo "🔄 发现本地依赖缓存,正在复制..." && \
mkdir -p node_modules && \
# 复制关键包
for pkg in "@prisma" ".prisma" "prisma" "sharp" "next" "react" "react-dom" "@aws-sdk" "three" "gsap"; do \
if [ -d "./cache_node_modules/$pkg" ]; then \
echo "📦 复制缓存包: $pkg" && \
cp -r "./cache_node_modules/$pkg" "./node_modules/" || true; \
fi; \
done; \
fi && \
# 执行npm install(会跳过已存在的包)
echo "📥 安装剩余依赖..." && \
npm ci --prefer-offline --no-audit || npm install --prefer-offline --no-audit
# 清理构建依赖
RUN apk del .build-deps && \
npm config delete registry && \
rm -rf ./cache_node_modules
# ============================================
# 阶段 3: 构建应用 (builder)
# ============================================
FROM base AS builder
# 构建参数
ARG DATABASE_URL=""
ARG NEXTAUTH_URL=""
ARG APP_PUBLIC_URL=""
# 环境变量
ENV DATABASE_URL=${DATABASE_URL}
ENV NEXTAUTH_URL=${NEXTAUTH_URL}
ENV APP_PUBLIC_URL=${APP_PUBLIC_URL}
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production
WORKDIR /app
# 安装OpenSSL(Prisma需要)
RUN apk add --no-cache openssl3
# 从deps阶段复制node_modules
COPY --from=deps /app/node_modules ./node_modules
# 复制应用源代码
COPY . .
# 复制本地Prisma引擎缓存(如果存在)
COPY cache/prisma-engines* ./prisma/engine-cache/ 2>/dev/null || true
# 配置Prisma引擎缓存路径
ENV PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1
ENV PRISMA_ENGINE_CACHE_PATH=/app/prisma/engine-cache/libquery_engine-linux-musl-openssl-3.0.x.so.node
ENV PRISMA_SCHEMA_ENGINE_CACHE_PATH=/app/prisma/engine-cache/schema-engine-linux-musl-openssl-3.0.x
# 智能生成Prisma Client:优先使用本地引擎
RUN set -ex && \
# 检查本地引擎缓存
if [ -f "${PRISMA_ENGINE_CACHE_PATH}" ]; then \
echo "🔧 使用本地Prisma查询引擎缓存" && \
export PRISMA_QUERY_ENGINE_LIBRARY="${PRISMA_ENGINE_CACHE_PATH}" && \
export PRISMA_CLIENT_ENGINE_TYPE=library && \
export PRISMA_CLI_QUERY_ENGINE_TYPE=library; \
else \
echo "⚠️ 本地Prisma引擎缓存不可用,将在线下载"; \
fi && \
if [ -f "${PRISMA_SCHEMA_ENGINE_CACHE_PATH}" ]; then \
echo "🔧 使用本地Prisma schema引擎缓存" && \
export PRISMA_SCHEMA_ENGINE_BINARY="${PRISMA_SCHEMA_ENGINE_CACHE_PATH}"; \
fi && \
# 生成Prisma Client
if npx prisma generate; then \
echo "✅ Prisma Client生成成功"; \
else \
echo "⚠️ 官方源失败,尝试镜像源..." && \
PRISMA_ENGINES_MIRROR="https://registry.npmmirror.com/-/binary/prisma/" npx prisma generate; \
fi
# 构建Next.js应用
RUN set -ex && \
echo "🏗️ 构建Next.js应用..." && \
npm run build && \
echo "✅ 构建完成"
# 验证构建产物
RUN if [ ! -f ".next/standalone/server.js" ]; then \
echo "❌ standalone输出未生成,请检查next.config.js配置" >&2 && \
exit 1; \
fi
# ============================================
# 阶段 4: 生产运行 (runner)
# ============================================
FROM base AS runner
WORKDIR /app
# 生产环境变量
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# 安装运行时依赖
RUN apk add --no-cache \
# 字体支持(3D渲染可能需要)
fontconfig \
ttf-dejavu \
# 图像处理(Sharp需要)
vips-dev
# 创建非root用户
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/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
# 复制关键运行时模块
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/prisma ./node_modules/prisma
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.bin ./node_modules/.bin
# 创建上传目录
RUN mkdir -p /app/uploads && \
chown -R nextjs:nodejs /app/uploads && \
chmod -R 755 /app/uploads
# 切换到非root用户
USER nextjs
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1
# 启动应用
CMD ["node", "server.js"]