Dockerfile.backend
Rama main · réplica de lectura del repositorio original.
FROM oven/bun:1.4.4-alpine AS base
WORKDIR /app
# --- Install dependencies ---
# A single root install creates /app/node_modules with hoisted deps and
# populates the workspace symlinks for backend/, frontend/, and packages/db/.
# The root install materializes the workspace links and hoisted dependencies;
# keeping a single install here also makes the image reproducible when Bun
# evaluates `workspace:*` dependencies from a package directory.
FROM base AS deps
COPY package.json bun.lock* ./
COPY vendor/deepmerge ./vendor/deepmerge
COPY backend/package.json ./backend/
COPY frontend/package.json ./frontend/
COPY packages/db/package.json ./packages/db/
COPY packages/sdk/package.json ./packages/sdk/
COPY packages/cli/package.json ./packages/cli/
COPY packages/mcp-server/package.json ./packages/mcp-server/
ENV BUN_INSTALL_CONCURRENCY=1
RUN --mount=type=cache,target=/root/.bun/install/cache bun install --frozen-lockfile
# --- Build ---
# Carry node_modules (workspace symlinks) from the deps stage, then layer
# backend source and the workspace package source (packages/db) on top. We
# pull packages/db from the build context because the deps stage only has
# its package.json (just enough for `bun install` to discover it).
FROM base AS build
COPY package.json tsconfig.json ./
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/vendor ./vendor
COPY --from=deps /app/backend/node_modules ./backend/node_modules
# Backend imports the public SDK/MCP exports. Materialize their workspace links
# and source so its build:server prerequisite works in a clean image too.
COPY --from=deps /app/packages/sdk/node_modules ./packages/sdk/node_modules
COPY --from=deps /app/packages/mcp-server/node_modules ./packages/mcp-server/node_modules
COPY packages/sdk/ ./packages/sdk/
COPY packages/mcp-server/ ./packages/mcp-server/
COPY packages/db/ ./packages/db/
COPY backend/src ./backend/src
COPY backend/tsconfig.json ./backend/
COPY backend/package.json ./backend/
RUN cd backend && bun run build
# --- Migration job ---
# This target contains only the DB workspace and its migration runner. It is
# used by docker-compose's one-shot `migrate` service and deliberately runs
# with MIGRATION_DATABASE_URL (the owner role), never DATABASE_URL.
FROM base AS migration
COPY package.json tsconfig.json ./
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/vendor ./vendor
COPY packages/db/ ./packages/db/
ENV NODE_ENV=production
WORKDIR /app/packages/db
CMD ["bun", "run", "scripts/migrate.ts"]
# --- Runtime ---
# Slim image: only the compiled dist + the root workspace dependency graph.
FROM base AS runtime
# Create the runtime identity before copying artifacts so BuildKit can assign
# ownership while materializing each layer. A recursive chown of the workspace
# dependency tree is prohibitively slow on overlay filesystems.
RUN addgroup -S app && adduser -S app -G app
COPY --chown=app:app --from=deps /app/node_modules ./node_modules
COPY --chown=app:app --from=deps /app/vendor ./vendor
COPY --chown=app:app --from=deps /app/backend/node_modules ./backend/node_modules
COPY --chown=app:app --from=build /app/backend/dist ./backend/dist
COPY --chown=app:app backend/package.json ./backend/
ENV NODE_ENV=production
ENV API_PORT=50700
WORKDIR /app/backend
USER app
HEALTHCHECK --interval=30s CMD wget -qO- http://localhost:50700/api/health || exit 1
EXPOSE 50700
CMD ["bun", "run", "dist/index.js"]