diff --git a/features/platform-admin/backend-api/Dockerfile b/features/platform-admin/backend-api/Dockerfile new file mode 100644 index 000000000..bc19eb93a --- /dev/null +++ b/features/platform-admin/backend-api/Dockerfile @@ -0,0 +1,106 @@ +# ============================================================================= +# Platform Admin Backend API - Multi-Target Dockerfile +# ============================================================================= +# +# Supports both development (with HMR) and production modes: +# +# Development: docker build --target development -t platform-admin-api:dev . +# Production: docker build --target production -t platform-admin-api:prod . +# +# In dev, source is mounted as volume for HMR. In prod, image contains built app. +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# BASE: Common setup for all stages +# ----------------------------------------------------------------------------- +FROM node:22-alpine AS base + +WORKDIR /app + +# Install pnpm globally +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Install build dependencies for native modules +RUN apk add --no-cache libc6-compat python3 make g++ + +# ----------------------------------------------------------------------------- +# DEVELOPMENT: Watch mode with source mounted at runtime +# ----------------------------------------------------------------------------- +FROM base AS development + +ENV NODE_ENV=development + +# Copy package files for dependency installation +COPY package.json pnpm-lock.yaml* ./ + +# Install all dependencies (including devDependencies) +RUN pnpm install --frozen-lockfile || pnpm install + +# Source code is mounted at runtime via volume - don't copy here +# The docker-compose.yml mounts: ./src:/app/src + +# Expose Platform Admin API port (from ports.yaml: features.platform-admin.api = 3011) +EXPOSE 3011 + +# Health check with longer start period for dev (slower cold start) +HEALTHCHECK --interval=10s --timeout=5s --start-period=60s --retries=5 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3011/health || exit 1 + +# Start in watch mode for HMR +CMD ["pnpm", "start:dev"] + +# ----------------------------------------------------------------------------- +# BUILDER: Compile TypeScript for production +# ----------------------------------------------------------------------------- +FROM base AS builder + +ENV NODE_ENV=production + +# Copy package files +COPY package.json pnpm-lock.yaml* ./ + +# Install dependencies (production + build tools) +RUN pnpm install --frozen-lockfile || pnpm install + +# Copy source code and config files +COPY src/ ./src/ +COPY scripts/ ./scripts/ +COPY tsconfig.json nest-cli.json .swcrc ./ + +# Build the application (includes ESM import fix) +RUN pnpm build + +# Prune dev dependencies after build +RUN pnpm prune --prod + +# ----------------------------------------------------------------------------- +# PRODUCTION: Minimal runtime image +# ----------------------------------------------------------------------------- +FROM node:22-alpine AS production + +WORKDIR /app + +ENV NODE_ENV=production + +# Create non-root user for security +RUN addgroup -g 1001 -S nodejs && \ + adduser -S nestjs -u 1001 + +# Copy only necessary files from builder +COPY --from=builder --chown=nestjs:nodejs /app/dist ./dist +COPY --from=builder --chown=nestjs:nodejs /app/node_modules ./node_modules +COPY --from=builder --chown=nestjs:nodejs /app/package.json ./ + +# Switch to non-root user +USER nestjs + +# Expose Platform Admin API port +EXPOSE 3011 + +# Health check for production (shorter intervals, faster detection) +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3011/health || exit 1 + +# Start the production server +CMD ["node", "dist/main.js"] diff --git a/features/platform-admin/frontend-admin/Dockerfile b/features/platform-admin/frontend-admin/Dockerfile new file mode 100644 index 000000000..c4e4d2bba --- /dev/null +++ b/features/platform-admin/frontend-admin/Dockerfile @@ -0,0 +1,109 @@ +# ============================================================================= +# Platform Admin Frontend - Multi-Target Dockerfile +# ============================================================================= +# +# Supports both development (with HMR) and production modes: +# +# Development: docker build --target development -t platform-admin-frontend:dev . +# Production: docker build --target production -t platform-admin-frontend:prod . +# +# In dev, source is mounted as volume for HMR. In prod, nginx serves static files. +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# BASE: Common setup for all stages +# ----------------------------------------------------------------------------- +FROM node:22-alpine AS base + +WORKDIR /app + +# Install pnpm globally +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Install build dependencies +RUN apk add --no-cache libc6-compat + +# ----------------------------------------------------------------------------- +# DEVELOPMENT: Vite dev server with HMR +# ----------------------------------------------------------------------------- +FROM base AS development + +ENV NODE_ENV=development + +# Copy package files for dependency installation +COPY package.json pnpm-lock.yaml* ./ + +# Install all dependencies (including devDependencies) +RUN pnpm install --frozen-lockfile || pnpm install + +# Source code is mounted at runtime via volume - don't copy here +# The docker-compose.yml mounts: ./src:/app/src + +# Copy essential config files (needed for Vite to start) +COPY index.html vite.config.ts tsconfig.json tsconfig.node.json ./ + +# Expose Platform Admin Frontend dev port (from ports.yaml: features.platform-admin.frontend-dev = 3200) +EXPOSE 3200 + +# Health check for Vite dev server +HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=5 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3200/ || exit 1 + +# Start Vite dev server with HMR enabled for Docker +# --host 0.0.0.0 ensures it's accessible from outside container +CMD ["pnpm", "dev", "--host", "0.0.0.0", "--port", "3200"] + +# ----------------------------------------------------------------------------- +# BUILDER: Build production assets +# ----------------------------------------------------------------------------- +FROM base AS builder + +ENV NODE_ENV=production + +# Copy package files +COPY package.json pnpm-lock.yaml* ./ + +# Install dependencies (production + build tools) +RUN pnpm install --frozen-lockfile || pnpm install + +# Copy source code and config files +COPY src/ ./src/ +COPY features/ ./features/ +COPY @packages/ ./@packages/ +COPY index.html vite.config.ts tsconfig.json tsconfig.node.json ./ + +# Build the application +RUN pnpm build + +# ----------------------------------------------------------------------------- +# PRODUCTION: Serve static files with nginx +# ----------------------------------------------------------------------------- +FROM nginx:alpine AS production + +# Copy built assets from builder +COPY --from=builder /app/dist /usr/share/nginx/html + +# Copy nginx configuration for SPA routing +RUN echo 'server { \ + listen 3200; \ + root /usr/share/nginx/html; \ + index index.html; \ + location / { \ + try_files $uri $uri/ /index.html; \ + } \ + location /assets { \ + expires 1y; \ + add_header Cache-Control "public, immutable"; \ + } \ +}' > /etc/nginx/conf.d/default.conf + +# Expose port +EXPOSE 3200 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3200/ || exit 1 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"]