Replace tsc with esbuild for building @multica/sdk and @multica/store in the Docker builder stage. esbuild resolves extensionless imports that Node.js ESM cannot handle at runtime, producing self-contained bundles for each workspace package. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
2.6 KiB
Docker
79 lines
2.6 KiB
Docker
# 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"]
|