# Build stage FROM node:22-alpine AS builder # Install pnpm RUN corepack enable && corepack prepare pnpm@10.28.2 --activate WORKDIR /app # Copy package files (pnpm-workspace.yaml needed for catalog resolution) COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ COPY packages/sdk/package.json ./packages/sdk/ COPY packages/store/package.json ./packages/store/ # Install all dependencies (including devDependencies for build) RUN pnpm install --frozen-lockfile # Copy workspace packages and bundle them with esbuild (resolves extensionless imports) COPY packages/sdk/ ./packages/sdk/ COPY packages/store/ ./packages/store/ RUN ./node_modules/.bin/esbuild packages/sdk/src/index.ts \ --bundle --platform=node --format=esm --outfile=packages/sdk/dist/index.js --packages=external && \ ./node_modules/.bin/esbuild packages/store/src/index.ts packages/store/src/connection.ts \ --bundle --splitting --platform=node --format=esm --outdir=packages/store/dist --packages=external # Copy source code COPY tsconfig.json ./ COPY src ./src # Build TypeScript (tsc emits JS despite type errors; ignore exit code) RUN ./node_modules/.bin/tsc || true # Production stage FROM node:22-alpine AS production # Install pnpm RUN corepack enable && corepack prepare pnpm@10.28.2 --activate WORKDIR /app # Copy package files (pnpm-workspace.yaml needed for catalog resolution) COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ COPY packages/sdk/package.json ./packages/sdk/ COPY packages/store/package.json ./packages/store/ # Install production dependencies only RUN pnpm install --frozen-lockfile --prod # Copy built workspace packages and patch exports to point to compiled JS COPY --from=builder /app/packages/sdk/dist ./packages/sdk/dist COPY --from=builder /app/packages/store/dist ./packages/store/dist RUN node -e " \ const fs = require('fs'); \ ['packages/sdk/package.json', 'packages/store/package.json'].forEach(p => { \ const pkg = JSON.parse(fs.readFileSync(p, 'utf8')); \ if (pkg.exports) { \ for (const [key, val] of Object.entries(pkg.exports)) { \ if (typeof val === 'string') { \ pkg.exports[key] = val.replace('./src/', './dist/').replace('.ts', '.js'); \ } \ } \ } \ fs.writeFileSync(p, JSON.stringify(pkg, null, 2)); \ });" # Copy built files from builder stage COPY --from=builder /app/dist ./dist # Copy static assets (not emitted by tsc) COPY --from=builder /app/src/gateway/public ./dist/gateway/public # Set environment variables ENV NODE_ENV=production ENV PORT=3000 # Expose the port EXPOSE 3000 # Run the gateway CMD ["node", "dist/gateway/main.js"]