64 lines
2.6 KiB
Docker
64 lines
2.6 KiB
Docker
FROM node:22-alpine AS base
|
|
RUN corepack enable && corepack prepare pnpm@latest --activate
|
|
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
|
|
COPY tooling/ ./tooling/
|
|
COPY packages/ ./packages/
|
|
COPY apps/ ./apps/
|
|
RUN pnpm install --frozen-lockfile
|
|
|
|
FROM deps AS builder
|
|
WORKDIR /app
|
|
|
|
# Generate Prisma client first (needed by @yetanother/db tsc build)
|
|
RUN pnpm --filter @yetanother/db exec prisma generate
|
|
|
|
# Compile all workspace dependency packages so their dist/ exists
|
|
RUN pnpm --filter @yetanother/db build
|
|
RUN pnpm --filter @yetanother/types build
|
|
RUN pnpm --filter @yetanother/utils build
|
|
|
|
RUN pnpm build --filter @yetanother/api
|
|
|
|
FROM builder AS deployer
|
|
WORKDIR /app
|
|
|
|
# Create a self-contained deployment with flat node_modules (no .pnpm symlinks)
|
|
# This ensures ALL transitive deps are resolvable by Node at runtime
|
|
RUN pnpm --filter @yetanother/api deploy --prod --legacy /deploy
|
|
|
|
# Copy compiled dist/ output (gitignored, so pnpm deploy excludes it)
|
|
RUN rm -rf /deploy/dist && cp -r /app/apps/api/dist /deploy/dist
|
|
RUN rm -rf /deploy/node_modules/@yetanother/db/dist && cp -r /app/packages/db/dist /deploy/node_modules/@yetanother/db/
|
|
RUN rm -rf /deploy/node_modules/@yetanother/types/dist && cp -r /app/packages/types/dist /deploy/node_modules/@yetanother/types/
|
|
RUN rm -rf /deploy/node_modules/@yetanother/utils/dist && cp -r /app/packages/utils/dist /deploy/node_modules/@yetanother/utils/
|
|
|
|
# Copy the real Prisma generated client from the builder's pnpm store
|
|
# (pnpm deploy's postinstall generates a stub since it has no schema; we replace it)
|
|
RUN PRISMA_CLIENT_DIR=$(ls -d /app/node_modules/.pnpm/@prisma+client* | head -1) && \
|
|
TARGET_DIR="/deploy/${PRISMA_CLIENT_DIR#/app/}/node_modules" && \
|
|
rm -rf "$TARGET_DIR/.prisma" && cp -r "$PRISMA_CLIENT_DIR/node_modules/.prisma" "$TARGET_DIR/.prisma"
|
|
|
|
# Copy Prisma schema
|
|
RUN rm -rf /deploy/prisma && cp -r /app/packages/db/prisma /deploy/prisma
|
|
|
|
# Fix workspace package main fields to point to compiled JS instead of TS
|
|
RUN for pkg in /deploy/node_modules/@yetanother/*/; do \
|
|
sed -i 's|"main": "./src/|"main": "./dist/src/|; /"main":/s/\.ts"/\.js"/' "$pkg/package.json"; \
|
|
done
|
|
|
|
# Add .js extensions to relative imports in compiled ESM output (TS doesn't add them)
|
|
RUN find -L /deploy/node_modules/@yetanother -name "*.js" -exec sed -i \
|
|
-e "s/\(from '\.\/[^'.]*\)'/\1.js'/g" \
|
|
-e "s/\(from '\.\.\/[^'.]*\)'/\1.js'/g" \
|
|
{} +
|
|
|
|
FROM node:22-alpine AS runner
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production
|
|
COPY --from=deployer /deploy .
|
|
EXPOSE 4000
|
|
CMD ["node", "dist/src/main.js"]
|