- Enabled workspace package injection in pnpm-lock.yaml for improved dependency management. - Removed outdated SHA256 files for backend and frontend tarballs. - Refactored Dockerfile for BFF to streamline the build process and optimize production image size. - Updated Prisma client configuration to specify binary targets for Alpine compatibility. - Enhanced error handling in WhmcsLinkWorkflowService to use BadRequestException for clearer client feedback. - Adjusted entrypoint script to ensure proper database migration execution.
129 lines
4.8 KiB
Docker
129 lines
4.8 KiB
Docker
# 🚀 Backend (BFF) Dockerfile - Production Grade (pnpm v10)
|
||
# - Uses pnpm's injected workspace packages (no legacy flags)
|
||
# - pnpm deploy creates minimal production-only install
|
||
# - Prisma + bcrypt built only for Alpine
|
||
# - No redundant installs
|
||
|
||
# =====================================================
|
||
# Stage 1: Dependencies (Debian for native builds)
|
||
# =====================================================
|
||
FROM node:22-bookworm-slim AS deps
|
||
|
||
RUN apt-get update && apt-get install -y dumb-init ca-certificates \
|
||
&& rm -rf /var/lib/apt/lists/* \
|
||
&& corepack enable && corepack prepare pnpm@10.15.0 --activate
|
||
|
||
WORKDIR /app
|
||
|
||
COPY .npmrc pnpm-workspace.yaml package.json pnpm-lock.yaml ./
|
||
COPY packages/domain/package.json ./packages/domain/
|
||
COPY packages/logging/package.json ./packages/logging/
|
||
COPY packages/validation/package.json ./packages/validation/
|
||
COPY apps/bff/package.json ./apps/bff/
|
||
|
||
RUN pnpm install --frozen-lockfile --prefer-offline --config.ignore-scripts=false
|
||
|
||
# =====================================================
|
||
# Stage 2: Builder (compile TypeScript)
|
||
# =====================================================
|
||
FROM node:22-bookworm-slim AS builder
|
||
|
||
RUN apt-get update && apt-get install -y ca-certificates \
|
||
&& rm -rf /var/lib/apt/lists/* \
|
||
&& corepack enable && corepack prepare pnpm@10.15.0 --activate
|
||
|
||
WORKDIR /app
|
||
|
||
COPY .npmrc pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.json tsconfig.base.json ./
|
||
COPY packages/ ./packages/
|
||
COPY apps/bff/ ./apps/bff/
|
||
COPY --from=deps /app/node_modules ./node_modules
|
||
|
||
# No second pnpm install – reuse deps layer
|
||
|
||
# Build shared packages
|
||
RUN pnpm --filter @customer-portal/domain build \
|
||
&& pnpm --filter @customer-portal/logging build \
|
||
&& pnpm --filter @customer-portal/validation build
|
||
|
||
# Build BFF (prisma types generated in dev, not needed here)
|
||
RUN pnpm --filter @customer-portal/bff build
|
||
|
||
# =====================================================
|
||
# Stage 3: Production Dependencies (Alpine, pnpm deploy)
|
||
# =====================================================
|
||
FROM node:22-alpine AS prod-deps
|
||
|
||
RUN corepack enable && corepack prepare pnpm@10.15.0 --activate
|
||
|
||
WORKDIR /app
|
||
|
||
# Minimal manifests for dependency graph
|
||
COPY .npmrc pnpm-workspace.yaml package.json pnpm-lock.yaml ./
|
||
COPY packages/domain/package.json ./packages/domain/
|
||
COPY packages/logging/package.json ./packages/logging/
|
||
COPY packages/validation/package.json ./packages/validation/
|
||
COPY apps/bff/package.json ./apps/bff/
|
||
COPY apps/bff/prisma ./apps/bff/prisma
|
||
|
||
ENV HUSKY=0
|
||
|
||
RUN apk add --no-cache --virtual .build-deps python3 make g++ pkgconfig openssl-dev \
|
||
# 1) Install full deps (needed for prisma CLI + bcrypt build)
|
||
&& pnpm install --frozen-lockfile --ignore-scripts \
|
||
# 2) Rebuild bcrypt for musl
|
||
&& pnpm rebuild bcrypt \
|
||
# 3) Generate Prisma client for Alpine (musl) – the only runtime client
|
||
&& cd apps/bff && pnpm exec prisma generate && cd ../.. \
|
||
# 4) Create production-only deployment for BFF
|
||
&& pnpm deploy --filter @customer-portal/bff --prod /app/deploy \
|
||
# 5) Remove build-time node_modules and cleanup
|
||
&& rm -rf /app/node_modules /app/pnpm-lock.yaml \
|
||
/root/.cache /root/.npm /tmp/* /var/cache/apk/* \
|
||
&& apk del .build-deps
|
||
|
||
# /app/deploy now contains: package.json + node_modules for BFF prod deps only
|
||
|
||
# =====================================================
|
||
# Stage 4: Production Runtime (minimal)
|
||
# =====================================================
|
||
FROM node:22-alpine AS production
|
||
|
||
RUN addgroup --system --gid 1001 nodejs \
|
||
&& adduser --system --uid 1001 nestjs
|
||
|
||
# Only tools needed at runtime
|
||
RUN apk add --no-cache wget dumb-init openssl netcat-openbsd \
|
||
&& rm -rf /var/cache/apk/*
|
||
|
||
WORKDIR /app
|
||
|
||
# Deploy tree (prod deps for BFF only)
|
||
COPY --from=prod-deps --chown=nestjs:nodejs /app/deploy ./
|
||
|
||
# Compiled code and prisma schema
|
||
COPY --from=builder --chown=nestjs:nodejs /app/packages/domain/dist ./packages/domain/dist
|
||
COPY --from=builder --chown=nestjs:nodejs /app/packages/logging/dist ./packages/logging/dist
|
||
COPY --from=builder --chown=nestjs:nodejs /app/packages/validation/dist ./packages/validation/dist
|
||
COPY --from=builder --chown=nestjs:nodejs /app/apps/bff/dist ./apps/bff/dist
|
||
COPY --from=builder --chown=nestjs:nodejs /app/apps/bff/prisma ./apps/bff/prisma
|
||
|
||
# Entrypoint and runtime dirs
|
||
COPY --chown=nestjs:nodejs apps/bff/scripts/docker-entrypoint.sh /app/docker-entrypoint.sh
|
||
RUN chmod +x /app/docker-entrypoint.sh \
|
||
&& mkdir -p /app/secrets /app/logs \
|
||
&& chown nestjs:nodejs /app/secrets /app/logs
|
||
|
||
USER nestjs
|
||
|
||
EXPOSE 4000
|
||
ENV NODE_ENV=production PORT=4000
|
||
|
||
WORKDIR /app/apps/bff
|
||
|
||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||
CMD wget --no-verbose --tries=1 --spider http://localhost:4000/health || exit 1
|
||
|
||
ENTRYPOINT ["dumb-init", "--", "/app/docker-entrypoint.sh"]
|
||
CMD ["node", "dist/main.js"]
|