# === STAGE 1: Build & Dependencies === FROM arm64v8/node:22 AS builder WORKDIR /app # Install pnpm and enable corepack RUN corepack enable && corepack prepare pnpm@latest --activate # Copy the lockfile and package.json to leverage caching COPY package.json pnpm-lock.yaml ./ # Use a cache mount to persist the pnpm store across builds. # The 'pnpm install' command will use this persistent cache. RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 \ pnpm install --frozen-lockfile # Copy the rest of the application files COPY . . # Use a second cache mount for the Vinxi build artifacts. RUN --mount=type=cache,target=/app/.vinxi \ pnpm run build # === STAGE 2: Generate Production-only Files === FROM arm64v8/node:22 AS production_builder RUN corepack enable && corepack prepare pnpm@latest --activate # Install jq to process the package.json file. # Note: jq is not in the base image, so we must install it. RUN apt-get update && apt-get install -y jq WORKDIR /app # Copy the original lockfile and package.json from the builder stage. COPY --from=builder /app/package.json ./ COPY --from=builder /app/pnpm-lock.yaml ./ # Create a new, production-only package.json file. # We use 'jq' to remove the 'devDependencies' key from the original package.json. RUN jq 'del(.devDependencies)' package.json > package.prod.json # Now, generate a production-only pnpm-lock.yaml # We run `pnpm install` again, but with `--prod`, and it will # generate a new lockfile based on the stripped-down dependencies. RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 pnpm install --prod RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 pnpm prune --prod # === STAGE 3: Final Production Image === FROM arm64v8/node:22-alpine WORKDIR /app # Enable corepack RUN corepack enable && corepack prepare pnpm@latest --activate # Copy the production-only files from the production_builder stage. COPY --from=production_builder /app/package.prod.json ./package.json COPY --from=production_builder /app/pnpm-lock.yaml ./pnpm-lock.yaml # Now pnpm install will be very fast, as the cache is not invalidated by devDependency changes. # It uses the production-only package.json and lockfile. RUN --mount=type=cache,target=/root/.local/share/pnpm/store/v3 \ pnpm install --frozen-lockfile --prod # Copy the compiled assets from the original builder stage. COPY --from=builder /app/.output ./.output EXPOSE 3000 CMD ["pnpm", "start"]