# ============================================================================== # Base stage - Common dependencies and setup # ============================================================================== # NOTE: This Dockerfile should be built from the monorepo root, not from apps/api # Build command: docker build -f apps/api/Dockerfile -t xtablo-api . FROM node:20-alpine AS base # Build argument for NODE_ENV ARG NODE_ENV=production # Install security updates and pnpm RUN apk --no-cache upgrade && \ corepack enable && \ corepack prepare pnpm@latest --activate # Create app directory and set up non-root user WORKDIR /app RUN addgroup -g 1001 -S nodejs RUN adduser -S nodejs -u 1001 # Copy workspace configuration and root package files COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./ # Copy packages directory (shared packages) COPY packages ./packages # Copy api app package.json COPY apps/api/package.json ./apps/api/package.json # ============================================================================== # Dependencies stage - Install all dependencies # ============================================================================== FROM base AS deps # Install all dependencies (including devDependencies for build) # This installs dependencies for the entire workspace RUN pnpm install --frozen-lockfile # ============================================================================== # Build stage - Compile TypeScript # ============================================================================== FROM deps AS build # Copy api source code COPY apps/api ./apps/api # Build the api application WORKDIR /app/apps/api RUN pnpm run build # ============================================================================== # Production dependencies stage - Install only production dependencies # ============================================================================== FROM base AS prod-deps # Install only production dependencies RUN pnpm install --frozen-lockfile --prod && pnpm store prune # ============================================================================== # Final stage - Production image # ============================================================================== FROM base AS final # Copy built api application COPY --from=build /app/apps/api/dist ./apps/api/dist COPY --from=build /app/apps/api/package.json ./apps/api/package.json # Copy shared packages (needed for workspace resolution) COPY --from=prod-deps /app/packages ./packages # Install production dependencies # This ensures proper symlink structure for pnpm RUN pnpm install --frozen-lockfile --prod --filter @xtablo/api... # Set working directory to api app WORKDIR /app/apps/api # Change ownership to nodejs user RUN chown -R nodejs:nodejs /app # Switch to non-root user USER nodejs # Expose port EXPOSE 8080 # NODE_ENV will be set via Cloud Run environment variables # Start the application CMD ["pnpm", "start"]