# syntax=docker/dockerfile:1.7 # ───────────────────────────────────────────────────────────────────────────── # Stage 1: Dependencies (production only) # ───────────────────────────────────────────────────────────────────────────── FROM node:22-bookworm-slim AS deps WORKDIR /app # Copy package files COPY package.json package-lock.json ./ # Install production dependencies only with cache mount RUN --mount=type=cache,target=/root/.npm \ npm ci --omit=dev --prefer-offline # ───────────────────────────────────────────────────────────────────────────── # Stage 2: Build # ───────────────────────────────────────────────────────────────────────────── FROM node:22-bookworm-slim AS build WORKDIR /app # Copy package files COPY package.json package-lock.json ./ # Install all dependencies (including devDependencies) with cache mount RUN --mount=type=cache,target=/root/.npm \ npm ci --prefer-offline # Copy TypeScript config COPY tsconfig.json tsconfig.build.json ./ # Copy source code COPY src ./src # Build TypeScript to JavaScript RUN npm run build # ───────────────────────────────────────────────────────────────────────────── # Stage 3: Runtime # ───────────────────────────────────────────────────────────────────────────── FROM node:22-bookworm-slim AS runtime # Set production environment ENV NODE_ENV=production WORKDIR /app # Install runtime dependencies and create non-root user RUN apt-get update && \ apt-get install -y --no-install-recommends \ tini \ ca-certificates \ curl && \ rm -rf /var/lib/apt/lists/* && \ useradd --system --uid 1001 --create-home agenthub # Copy production dependencies from deps stage COPY --from=deps --chown=agenthub:agenthub /app/node_modules ./node_modules # Copy built application from build stage COPY --from=build --chown=agenthub:agenthub /app/dist ./dist # Copy package.json for metadata COPY --chown=agenthub:agenthub package.json ./ # Copy Drizzle migrations (required for npm run migrate) COPY --chown=agenthub:agenthub drizzle ./drizzle COPY --chown=agenthub:agenthub drizzle.config.ts ./ # Copy migration and seed scripts COPY --chown=agenthub:agenthub scripts ./scripts # Switch to non-root user USER agenthub # Expose application port EXPOSE 3000 # Add healthcheck HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=10s \ CMD curl -f http://127.0.0.1:3000/healthz || exit 1 # Use tini as init system for proper signal handling ENTRYPOINT ["/usr/bin/tini", "--"] # Start the application CMD ["node", "dist/server.js"]