ARG NODE_VERSION=22.21.1 # Base FROM node:${NODE_VERSION} AS base WORKDIR /app RUN apt-get update && \ apt-get upgrade -y && \ rm -rf /var/lib/apt/lists ENV PNPM_HOME=/pnpm ENV PATH=$PNPM_HOME:$PNPM_HOME/bin:$PATH RUN corepack enable RUN corepack prepare pnpm@11.5.0 --activate RUN pnpm add -g turbo RUN pnpm add -g tsx # Prune stage FROM base AS pruner COPY . . RUN tsx ./scripts/generate-sdks.ts # https://turbo.build/repo/docs/guides/tools/docker RUN turbo prune --scope=@hexclave/backend --scope=@hexclave/dashboard --docker # Build stage FROM base AS builder # Skip generate-sdks.ts in preinstall hook (file not available in pruned output) ENV STACK_SKIP_TEMPLATE_GENERATION=true # copy over package.json files and install dependencies COPY --from=pruner /app/out/json/ . COPY --from=pruner /app/out/pnpm-lock.yaml . COPY .gitignore . COPY pnpm-workspace.yaml . COPY turbo.json . COPY configs ./configs COPY --from=pruner /app/scripts/postinstall-patch-next-async-debug-info.mjs ./scripts/ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile # copy over the rest of the code for the build COPY --from=pruner /app/out/full/ . # docs are currently required for the NextJS backend build, but won't exist in the final image COPY docs ./docs # https://nextjs.org/docs/pages/api-reference/next-config-js/output ENV NEXT_CONFIG_OUTPUT=standalone # Build the backend NextJS app RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm turbo run docker-build --filter=@hexclave/backend... --filter=@hexclave/dashboard... # Build the self-host seed script RUN --mount=type=cache,id=pnpm,target=/pnpm/store cd apps/backend && pnpm build-self-host-migration-script # Final image FROM node:${NODE_VERSION}-slim WORKDIR /app # Install packages needed for deployment RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y openssl socat && \ rm -rf /var/lib/apt/lists # Copy built backend COPY --from=builder --chown=node:node /app/apps/backend/.next/standalone ./ COPY --from=builder --chown=node:node /app/apps/backend/.next/static ./apps/backend/.next/static COPY --from=builder --chown=node:node /app/apps/backend/prisma ./apps/backend/prisma COPY --from=builder --chown=node:node /app/apps/backend/dist ./apps/backend/dist COPY --from=builder --chown=node:node /app/apps/backend/node_modules ./apps/backend/node_modules # Copy built dashboard COPY --from=builder --chown=node:node /app/apps/dashboard/.next/standalone ./ COPY --from=builder --chown=node:node /app/apps/dashboard/.next/static ./apps/dashboard/.next/static COPY --from=builder --chown=node:node /app/apps/dashboard/public ./apps/dashboard/public # Restore workspace node_modules needed by non-Next runtime scripts (e.g. migrations) COPY --from=builder --chown=node:node /app/node_modules ./node_modules COPY --from=builder --chown=node:node /app/packages ./packages # Add the entrypoint script COPY ./docker/server/entrypoint.sh . RUN chmod +x entrypoint.sh WORKDIR /app # Define environment variables for both services ENV NODE_ENV=production ENV BACKEND_PORT=8102 ENV DASHBOARD_PORT=8101 USER node # Set entrypoint to run both backend and dashboard ENTRYPOINT ["./entrypoint.sh"]