# syntax=docker/dockerfile:1.7 # ============================================================================= # Rubis — image API (AdonisJS V7, Node 22) # Sert /api/v1/* en interne au cluster (ClusterIP rubis-api:3333). # Le SPA est servi par rubis-web (nginx) en frontal qui proxy /api/* ici. # ============================================================================= # # Workers BullMQ tournent dans le même process Node (cf. start/queue.ts). # Migrations exécutées par init-container avant le serveur (cf. k3s/app/api.yml). # # Particularités : # - On bypasse @poppinss/ts-exec en appelant ace via tsx (ERR_UNKNOWN_FILE # _EXTENSION sinon, swc/core race au boot) # - --ignore-ts-errors car tests/bootstrap.ts réfère un type généré tardif # ============================================================================= ARG NODE_VERSION=22.13.1 ARG PNPM_VERSION=10.0.0 # ----------------------------------------------------------------------------- # base — node + pnpm + tini # ----------------------------------------------------------------------------- FROM node:${NODE_VERSION}-alpine AS base ARG PNPM_VERSION RUN apk add --no-cache libc6-compat tini && \ corepack enable && \ corepack prepare pnpm@${PNPM_VERSION} --activate WORKDIR /repo # ----------------------------------------------------------------------------- # deps — install workspace (avec devDeps pour le build) # ----------------------------------------------------------------------------- FROM base AS deps COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json tsconfig.base.json ./ COPY apps/api/package.json ./apps/api/ COPY packages/shared/package.json ./packages/shared/ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \ pnpm install --frozen-lockfile # ----------------------------------------------------------------------------- # build — ace build via tsx # ----------------------------------------------------------------------------- FROM deps AS build COPY packages/shared ./packages/shared COPY apps/api ./apps/api # Inclus les PDFs de démo pour le command `seed:demo` (lancé manuellement # en prod via `kubectl exec`). 27 fichiers, ~80KB total — négligeable. COPY assets ./assets RUN cd apps/api && pnpm exec tsx ace.js build --ignore-ts-errors # Prune devDeps (les workspace symlinks restent). RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \ pnpm install --prod --frozen-lockfile=false # ----------------------------------------------------------------------------- # runner — runtime minimal, user non-root # ----------------------------------------------------------------------------- FROM base AS runner RUN addgroup -g 1001 -S nodejs && adduser -S adonis -u 1001 ENV NODE_ENV=production \ HOST=0.0.0.0 \ PORT=3333 \ LOG_LEVEL=info WORKDIR /app COPY --from=build --chown=adonis:nodejs /repo /app USER adonis WORKDIR /app/apps/api EXPOSE 3333 # /api/v1/health renvoie 200 quand le serveur + DB sont up. HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD wget -qO- http://127.0.0.1:3333/api/v1/health >/dev/null 2>&1 || exit 1 ENTRYPOINT ["/sbin/tini", "--"] CMD ["node", "build/bin/server.js"]