# syntax=docker/dockerfile:1 # ---------- Etape 1 : build du backend NestJS ---------- FROM node:20-bookworm AS backend-build WORKDIR /app COPY package.json package-lock.json* ./ RUN npm install COPY tsconfig.json tsconfig.build.json nest-cli.json eslint.config.mjs ./ COPY src ./src # Portes de qualite : le build Docker (donc le deploiement Coolify) echoue si l'une de ces # etapes echoue. Voir CLAUDE.md pour le detail des scripts. RUN npm run lint RUN npm run typecheck RUN npm run test RUN npm run build RUN npm prune --omit=dev # ---------- Etape 2 : image finale ---------- # Debian trixie fournit CloudCompare 2.13.2 directement en apt (paquet "cloudcompare"), # ce qui evite une compilation depuis les sources (tres longue et fragile). FROM debian:trixie-slim ENV DEBIAN_FRONTEND=noninteractive \ NODE_ENV=production \ DATA_DIR=/data \ CLOUDCOMPARE_BIN=CloudCompare \ PYTHON_BIN=python3 \ DISPLAY=:99 RUN apt-get update && apt-get install -y --no-install-recommends \ cloudcompare \ xvfb \ x11-utils \ ca-certificates \ curl \ gnupg \ python3 \ python3-pip \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && rm -rf /var/lib/apt/lists/* COPY python/requirements.txt /app/python/requirements.txt RUN pip3 install --break-system-packages --no-cache-dir -r /app/python/requirements.txt WORKDIR /app COPY --from=backend-build /app/node_modules ./node_modules COPY --from=backend-build /app/dist ./dist COPY package.json ./ COPY python ./python COPY public ./public COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh && mkdir -p /data # Utilisateur non-root : l'image debian:trixie-slim + nodejs (nodesource) n'a pas d'utilisateur # "node" preexistant (contrairement a l'image officielle node:*). /app et /data sont chown AVANT # la directive VOLUME pour que l'appartenance soit reprise par le volume nomme Coolify/Compose a # sa premiere creation (Docker copie le contenu existant du repertoire dans un volume vide neuf). # /tmp/.X11-unix doit exister et etre world-writable (mode 1777, meme convention que /tmp) AVANT # de passer en non-root : Xvfb refuse de creer ce repertoire lui-meme si euid != 0 # ("_XSERVTransmkdir: ERROR: euid != 0"), il ne peut alors plus creer son socket X11 - verifie # empiriquement, le healthcheck HTTP passe quand meme (Xvfb echoue silencieusement en arriere-plan) # mais tout appel CloudCompare plante ensuite faute de display. RUN useradd --create-home --uid 1000 --shell /usr/sbin/nologin appuser \ && mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix \ && chown -R appuser:appuser /app /data VOLUME ["/data"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD curl -fsS "http://localhost:${PORT:-3000}/health" || exit 1 USER appuser ENTRYPOINT ["/entrypoint.sh"]