- Updated SHA256 checksums for the latest portal backend and frontend tar.gz files to reflect new builds. - Modified Dockerfile in both BFF and Portal applications to include additional TypeScript configuration files, improving build accuracy and consistency. - Enhanced the docker-entrypoint.sh script to utilize the updated Prisma configuration for migrations, ensuring compatibility with the latest Prisma CLI changes. - Improved error handling in Salesforce connection service to validate private key formats more robustly, enhancing security during JWT assertion creation.
105 lines
3.9 KiB
Docker
105 lines
3.9 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# =============================================================================
|
|
# Portal (Next.js) Dockerfile
|
|
# =============================================================================
|
|
# Multi-stage build with standalone output for minimal image size
|
|
# Optimized for fast builds, security, and small production images
|
|
# =============================================================================
|
|
|
|
ARG NODE_VERSION=22
|
|
ARG PNPM_VERSION=10.25.0
|
|
|
|
# =============================================================================
|
|
# Stage 1: Dependencies (cached layer)
|
|
# =============================================================================
|
|
FROM node:${NODE_VERSION}-alpine AS deps
|
|
|
|
ARG PNPM_VERSION
|
|
|
|
# Install build dependencies
|
|
RUN apk add --no-cache libc6-compat \
|
|
&& corepack enable \
|
|
&& corepack prepare pnpm@${PNPM_VERSION} --activate
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy manifests first for dependency caching (all workspace packages)
|
|
COPY .npmrc pnpm-workspace.yaml package.json pnpm-lock.yaml ./
|
|
COPY packages/domain/package.json ./packages/domain/package.json
|
|
COPY apps/portal/package.json ./apps/portal/package.json
|
|
COPY apps/bff/package.json ./apps/bff/package.json
|
|
|
|
# Install only the packages needed for the portal (domain + portal)
|
|
ENV HUSKY=0
|
|
RUN --mount=type=cache,id=pnpm-portal,target=/root/.local/share/pnpm/store \
|
|
pnpm install --frozen-lockfile --filter @customer-portal/domain... --filter @customer-portal/portal...
|
|
|
|
# =============================================================================
|
|
# Stage 2: Builder
|
|
# =============================================================================
|
|
FROM deps AS builder
|
|
|
|
# Copy source files
|
|
COPY tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.next.json ./
|
|
COPY packages/domain/ ./packages/domain/
|
|
COPY apps/portal/ ./apps/portal/
|
|
|
|
# Build-time environment variables
|
|
ARG NEXT_PUBLIC_API_BASE=/api
|
|
ARG NEXT_PUBLIC_APP_NAME="Customer Portal"
|
|
ARG NEXT_PUBLIC_APP_VERSION=1.0.0
|
|
|
|
ENV NODE_ENV=production \
|
|
NEXT_PUBLIC_API_BASE=${NEXT_PUBLIC_API_BASE} \
|
|
NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME} \
|
|
NEXT_PUBLIC_APP_VERSION=${NEXT_PUBLIC_APP_VERSION} \
|
|
NEXT_TELEMETRY_DISABLED=1
|
|
|
|
# Build: domain → Next.js (standalone output)
|
|
RUN pnpm --filter @customer-portal/domain build \
|
|
&& pnpm --filter @customer-portal/portal build
|
|
|
|
# =============================================================================
|
|
# Stage 3: Production
|
|
# =============================================================================
|
|
FROM node:${NODE_VERSION}-alpine AS production
|
|
|
|
LABEL org.opencontainers.image.title="Customer Portal Frontend" \
|
|
org.opencontainers.image.description="Next.js Customer Portal" \
|
|
org.opencontainers.image.vendor="Customer Portal"
|
|
|
|
# Minimal runtime dependencies + security hardening
|
|
RUN apk add --no-cache dumb-init libc6-compat \
|
|
&& addgroup --system --gid 1001 nodejs \
|
|
&& adduser --system --uid 1001 nextjs \
|
|
# Remove apk cache and unnecessary files
|
|
&& rm -rf /var/cache/apk/* /tmp/* /root/.npm
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy standalone build artifacts with correct ownership
|
|
COPY --from=builder --chown=nextjs:nodejs /app/apps/portal/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/apps/portal/.next/static ./apps/portal/.next/static
|
|
COPY --from=builder --chown=nextjs:nodejs /app/apps/portal/public ./apps/portal/public
|
|
|
|
# Security: Run as non-root user
|
|
USER nextjs
|
|
|
|
# Expose frontend port
|
|
EXPOSE 3000
|
|
|
|
# Environment configuration
|
|
ENV NODE_ENV=production \
|
|
NEXT_TELEMETRY_DISABLED=1 \
|
|
PORT=3000 \
|
|
HOSTNAME="0.0.0.0" \
|
|
# Node.js production optimizations
|
|
NODE_OPTIONS="--max-old-space-size=512"
|
|
|
|
# Health check for container orchestration
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
|
CMD node -e "fetch('http://localhost:3000/_health').then(r=>r.ok||process.exit(1)).catch(()=>process.exit(1))"
|
|
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["node", "apps/portal/server.js"]
|