# syntax=docker/dockerfile:1.7 # ============================================================================= # Rubis — image landing (Astro 6, React 19, Node SSR standalone) # Sert rubis.pro (landing + pages légales + blog SSR fetch via apps/api). # ============================================================================= # # Astro adapter: @astrojs/node en mode "standalone" → bundle un mini-server # Node dans dist/server/entry.mjs. Le bundle référence quand même certaines # deps externes (react, react-dom, lucide-react, sharp...), donc on copie # le workspace entier dans le runner stage avec les node_modules pruned # (--prod). Stratégie miroir de Dockerfile.api. # ============================================================================= 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 Astro) # ----------------------------------------------------------------------------- FROM base AS deps COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json tsconfig.base.json ./ COPY apps/landing/package.json ./apps/landing/ COPY packages/shared/package.json ./packages/shared/ COPY packages/ui/package.json ./packages/ui/ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \ pnpm install --frozen-lockfile --filter @rubis/landing... # ----------------------------------------------------------------------------- # build — astro build (output: server, adapter Node standalone) # ----------------------------------------------------------------------------- FROM deps AS build COPY packages/shared ./packages/shared COPY packages/ui ./packages/ui COPY apps/landing ./apps/landing RUN cd apps/landing && pnpm exec astro build # Prune devDeps. Les workspace symlinks restent intacts. Le stage runner # copie ensuite le repo entier — pnpm a besoin de la structure complète # pour résoudre les imports (workspace + hoist). RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \ pnpm install --prod --frozen-lockfile=false --filter @rubis/landing... # ----------------------------------------------------------------------------- # runner — runtime minimal, user non-root # ----------------------------------------------------------------------------- FROM base AS runner RUN addgroup -g 1001 -S nodejs && adduser -S astro -u 1001 ENV NODE_ENV=production \ HOST=0.0.0.0 \ PORT=4321 \ LOG_LEVEL=info WORKDIR /app # Copie le repo entier (avec node_modules prod pruned + workspace symlinks # + dist/ Astro). Node résout les imports via /app/apps/landing/node_modules # puis remonte dans /app/node_modules (hoisted). COPY --from=build --chown=astro:nodejs /repo /app USER astro WORKDIR /app/apps/landing EXPOSE 4321 # Healthcheck : / répond 200 (prerendered, pas besoin de l'API). HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ CMD wget -qO- http://127.0.0.1:4321/ >/dev/null 2>&1 || exit 1 ENTRYPOINT ["/sbin/tini", "--"] CMD ["node", "./dist/server/entry.mjs"]