mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 01:21:09 +02:00
After the planta + nutriphi modules in apps/api started importing
shared Zod schemas from @mana/shared-types, the runtime crashed in
a restart loop with:
error: ENOENT reading "/app/apps/api/node_modules/@mana/shared-types"
Same root cause as the @mana/media-client gotcha already in this
Dockerfile: the build context only includes the workspace packages
that are explicitly COPYed, and shared-types was missed when it
became a transitive dependency.
Add the COPY line and rebuild. Also extend the comment block to
make the rule explicit ("when adding a new @mana/* import to any
apps/api module, add the package here too").
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
71 lines
2.9 KiB
Docker
71 lines
2.9 KiB
Docker
# syntax=docker/dockerfile:1
|
|
#
|
|
# apps/api — unified Hono/Bun API server
|
|
#
|
|
# Multi-stage build:
|
|
# - builder: node:20-alpine with pnpm to resolve the workspace
|
|
# dependency graph (@mana/shared-hono + 3 more workspace packages).
|
|
# Bun's install command doesn't read pnpm-workspace.yaml, so we use
|
|
# pnpm here even though the runtime is Bun.
|
|
# - runtime: oven/bun:1 to actually run the server. Bun handles the
|
|
# pnpm symlink farm at node_modules/.pnpm/* natively, so the only
|
|
# thing the runtime stage needs is the workspace tree the builder
|
|
# produced and the entry script.
|
|
#
|
|
# Build context MUST be the monorepo root, not apps/api/. The compose
|
|
# service uses `context: .` for this reason.
|
|
|
|
FROM node:20-alpine AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
RUN npm install -g pnpm@9.15.0
|
|
|
|
# Copy the workspace manifest first so the dependency graph is known
|
|
# before we add source. This caches the install layer for incremental
|
|
# rebuilds when only source changes.
|
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
|
COPY apps/api/package.json ./apps/api/package.json
|
|
|
|
# Workspace packages that apps/api depends on, plus their transitive
|
|
# workspace deps. Listed explicitly so the install layer doesn't pull
|
|
# in the entire monorepo. When adding a new @mana/* import to any
|
|
# apps/api module, add the package here too — otherwise the runtime
|
|
# fails with "ENOENT reading /app/apps/api/node_modules/@mana/<x>".
|
|
COPY packages/shared-hono ./packages/shared-hono
|
|
COPY packages/shared-logger ./packages/shared-logger
|
|
COPY packages/shared-storage ./packages/shared-storage
|
|
COPY packages/shared-types ./packages/shared-types
|
|
# @mana/media-client lives under services/mana-media (sub-package).
|
|
COPY services/mana-media/packages/client ./services/mana-media/packages/client
|
|
|
|
# Resolve the dependency graph for apps/api only (--filter ...
|
|
# follows the workspace transitive deps automatically).
|
|
RUN pnpm install --filter @mana/api... --no-frozen-lockfile --ignore-scripts
|
|
|
|
# Copy the api source and tsconfig last so source-only changes don't
|
|
# bust the install cache.
|
|
COPY apps/api/src ./apps/api/src
|
|
COPY apps/api/tsconfig.json ./apps/api/tsconfig.json
|
|
|
|
|
|
# ─── Runtime stage ─────────────────────────────────────────────
|
|
#
|
|
# Bun can run TypeScript directly without a compile step, so the
|
|
# runtime image just needs the workspace tree the builder produced.
|
|
# We copy /app wholesale rather than try to slice node_modules — the
|
|
# pnpm symlink farm is fragile and easy to break with selective copies.
|
|
|
|
FROM oven/bun:1 AS production
|
|
|
|
WORKDIR /app
|
|
COPY --from=builder /app /app
|
|
|
|
WORKDIR /app/apps/api
|
|
|
|
EXPOSE 3060
|
|
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
|
|
CMD bun -e "fetch('http://localhost:3060/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
|
|
|
CMD ["bun", "run", "src/index.ts"]
|