All checks were successful
ci/woodpecker/push/ci Pipeline was successful
The .npmrc file contains supportedArchitectures settings to force pnpm to install glibc x64 binaries for native modules like matrix-sdk-crypto-nodejs. Without copying this file into the Docker image, pnpm defaults to the platform's native behavior which may skip or install incorrect binaries.
112 lines
4.1 KiB
Docker
112 lines
4.1 KiB
Docker
# Base image for all stages
|
|
# Uses Debian slim (glibc) instead of Alpine (musl) for native addon compatibility.
|
|
FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS base
|
|
|
|
# Install pnpm globally
|
|
RUN corepack enable && corepack prepare pnpm@10.27.0 --activate
|
|
|
|
# Set working directory
|
|
WORKDIR /app
|
|
|
|
# Copy monorepo configuration files
|
|
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
|
|
COPY turbo.json ./
|
|
|
|
# ======================
|
|
# Dependencies stage
|
|
# ======================
|
|
FROM base AS deps
|
|
|
|
# Copy all package.json files for workspace resolution
|
|
COPY packages/shared/package.json ./packages/shared/
|
|
COPY packages/config/package.json ./packages/config/
|
|
COPY apps/orchestrator/package.json ./apps/orchestrator/
|
|
|
|
# Copy npm configuration for native binary architecture hints
|
|
COPY .npmrc ./
|
|
|
|
# Install ALL dependencies (not just production)
|
|
# No cache mount — Kaniko builds are ephemeral in CI
|
|
RUN pnpm install --frozen-lockfile
|
|
|
|
# ======================
|
|
# Builder stage
|
|
# ======================
|
|
FROM base AS builder
|
|
|
|
# Copy root node_modules from deps
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
|
|
# Copy all source code
|
|
COPY packages ./packages
|
|
COPY apps/orchestrator ./apps/orchestrator
|
|
|
|
# Copy workspace node_modules from deps
|
|
COPY --from=deps /app/packages/shared/node_modules ./packages/shared/node_modules
|
|
COPY --from=deps /app/packages/config/node_modules ./packages/config/node_modules
|
|
COPY --from=deps /app/apps/orchestrator/node_modules ./apps/orchestrator/node_modules
|
|
|
|
# Build the orchestrator app using TurboRepo
|
|
RUN pnpm turbo build --filter=@mosaic/orchestrator
|
|
|
|
# Remove compiled test/spec files from dist BEFORE copying to production.
|
|
# These contain test fixture secrets (fake AWS keys, RSA keys) that trigger Trivy.
|
|
# Must happen in builder stage so they never appear in any production image layer.
|
|
RUN find ./apps/orchestrator/dist \( -name '*.spec.js' -o -name '*.spec.js.map' -o -name '*.test.js' -o -name '*.test.js.map' \) -delete
|
|
|
|
# ======================
|
|
# Production stage
|
|
# ======================
|
|
FROM git.mosaicstack.dev/mosaic/node-base:24-slim AS production
|
|
|
|
# Add metadata labels
|
|
LABEL maintainer="mosaic-team@mosaicstack.dev"
|
|
LABEL version="0.0.6"
|
|
LABEL description="Mosaic Orchestrator - Agent orchestration service"
|
|
LABEL org.opencontainers.image.source="https://git.mosaicstack.dev/mosaic/stack"
|
|
LABEL org.opencontainers.image.vendor="Mosaic Stack"
|
|
LABEL org.opencontainers.image.title="Mosaic Orchestrator"
|
|
LABEL org.opencontainers.image.description="Agent orchestration service for Mosaic Stack"
|
|
|
|
# dumb-init, ca-certificates pre-installed in base image
|
|
|
|
# Single RUN to minimize Kaniko filesystem snapshots (each RUN = full snapshot)
|
|
# - Remove npm/npx to reduce image size (not used in production)
|
|
# - Create non-root user
|
|
RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \
|
|
&& groupadd -g 1001 nodejs && useradd -m -u 1001 -g nodejs nestjs
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy node_modules from builder (includes all dependencies)
|
|
COPY --from=builder --chown=nestjs:nodejs /app/node_modules ./node_modules
|
|
|
|
# Copy built packages (includes dist/ directories)
|
|
COPY --from=builder --chown=nestjs:nodejs /app/packages ./packages
|
|
|
|
# Copy built orchestrator application (spec/test files already removed in builder stage)
|
|
COPY --from=builder --chown=nestjs:nodejs /app/apps/orchestrator/dist ./apps/orchestrator/dist
|
|
COPY --from=builder --chown=nestjs:nodejs /app/apps/orchestrator/package.json ./apps/orchestrator/
|
|
|
|
# Copy app's node_modules which contains symlinks to root node_modules
|
|
COPY --from=builder --chown=nestjs:nodejs /app/apps/orchestrator/node_modules ./apps/orchestrator/node_modules
|
|
|
|
# Set working directory to orchestrator app
|
|
WORKDIR /app/apps/orchestrator
|
|
|
|
# Switch to non-root user
|
|
USER nestjs
|
|
|
|
# Expose orchestrator port
|
|
EXPOSE 3001
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
|
CMD node -e "require('http').get('http://localhost:3001/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
|
|
|
# Use dumb-init to handle signals properly
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
|
|
# Start the application
|
|
CMD ["node", "dist/main.js"]
|