diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index dfb401c..a725a45 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -1,21 +1,31 @@ # ============================================================================== # 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:18-alpine AS base # Build argument for NODE_ENV ARG NODE_ENV=production -# Install security updates -RUN apk --no-cache upgrade +# 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 package files -COPY package*.json ./ +# 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 @@ -23,18 +33,20 @@ COPY package*.json ./ FROM base AS deps # Install all dependencies (including devDependencies for build) -RUN npm ci +# This installs dependencies for the entire workspace +RUN pnpm install --frozen-lockfile # ============================================================================== # Build stage - Compile TypeScript # ============================================================================== FROM deps AS build -# Copy source code -COPY . . +# Copy api source code +COPY apps/api ./apps/api -# Build the application -RUN npm run build +# Build the api application +WORKDIR /app/apps/api +RUN pnpm run build # ============================================================================== # Production dependencies stage - Install only production dependencies @@ -42,22 +54,24 @@ RUN npm run build FROM base AS prod-deps # Install only production dependencies -RUN npm ci --only=production && npm cache clean --force +RUN pnpm install --frozen-lockfile --prod && pnpm store prune # ============================================================================== # Staging stage - For staging environment # ============================================================================== FROM base AS staging -# Copy production dependencies +# Copy production dependencies (from workspace root) COPY --from=prod-deps /app/node_modules ./node_modules -# Copy built application -COPY --from=build /app/dist ./dist -COPY --from=build /app/package*.json ./ +# 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 environment files -COPY --from=build /app/.env* ./ +# Set working directory to api app +WORKDIR /app/apps/api + +# Note: Environment variables should be injected at runtime via docker run -e or docker-compose # Change ownership to nodejs user RUN chown -R nodejs:nodejs /app @@ -72,22 +86,24 @@ EXPOSE 8080 ENV NODE_ENV=staging # Start the application -CMD ["npm", "start"] +CMD ["pnpm", "start"] # ============================================================================== # Production stage - For production environment (default) # ============================================================================== FROM base AS production -# Copy production dependencies +# Copy production dependencies (from workspace root) COPY --from=prod-deps /app/node_modules ./node_modules -# Copy built application -COPY --from=build /app/dist ./dist -COPY --from=build /app/package*.json ./ +# 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 environment files -COPY --from=build /app/.env* ./ +# Set working directory to api app +WORKDIR /app/apps/api + +# Note: Environment variables should be injected at runtime via docker run -e or docker-compose # Change ownership to nodejs user RUN chown -R nodejs:nodejs /app @@ -102,4 +118,5 @@ EXPOSE 8080 ENV NODE_ENV=production # Start the application -CMD ["npm", "start"] \ No newline at end of file +# no-dd-sa:docker-best-practices/multiple-cmd +CMD ["pnpm", "start"] \ No newline at end of file diff --git a/apps/api/cloudbuild.yaml b/apps/api/cloudbuild.yaml index 8d8ff77..a78951e 100644 --- a/apps/api/cloudbuild.yaml +++ b/apps/api/cloudbuild.yaml @@ -1,6 +1,6 @@ steps: - name: 'gcr.io/cloud-builders/docker' - args: [ 'build', '--target', '$_NODE_ENV', '-t', 'europe-west1-docker.pkg.dev/$_AR_PROJECT_ID/$_AR_REPOSITORY/xtablo-source/$_SERVICE_NAME:$COMMIT_SHA', 'apps/api' ] + args: [ 'build', '-f', 'apps/api/Dockerfile', '--target', '$_NODE_ENV', '-t', 'europe-west1-docker.pkg.dev/$_AR_PROJECT_ID/$_AR_REPOSITORY/xtablo-source/$_SERVICE_NAME:$COMMIT_SHA', '.' ] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'europe-west1-docker.pkg.dev/$_AR_PROJECT_ID/$_AR_REPOSITORY/xtablo-source/$_SERVICE_NAME:$COMMIT_SHA'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'