> ## Documentation Index
> Fetch the complete documentation index at: https://infra-docs.kaeyros.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Dockerfile gabarit pour les services backend Kaeyros

> Pattern multi-stage pour containeriser les backends Kaeyros. Minimisation de l'image, sécurité non-root, healthcheck HTTP et cache optimisé des layers Docker.

Les services backend chez Kaeyros Analytics (majoritairement Node.js, avec des composants Python et Rust) suivent un pattern Dockerfile multi-stage standardisé. Ce gabarit minimise la taille de l'image finale, élimine les dépendances de build inutiles et renforce la sécurité avec un utilisateur non-root.

## Dockerfile gabarit complet

```dockerfile Dockerfile theme={null}
# syntax=docker/dockerfile:1

# ============================================
# Stage 1 : Dépendances de production
# ============================================
FROM node:20-alpine AS deps
WORKDIR /app

# Copie isolée des manifests pour optimiser le cache
COPY package.json package-lock.json ./

# Installation des dépendances de production uniquement
RUN npm ci --omit=dev --ignore-scripts && \
    npm cache clean --force

# ============================================
# Stage 2 : Build de l'application
# ============================================
FROM node:20-alpine AS build
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts

# Copie du code source après installation des déps
COPY . .

# Compilation TypeScript / bundling
RUN npm run build

# Suppression des devDependencies après build
RUN npm prune --omit=dev

# ============================================
# Stage 3 : Image de production
# ============================================
FROM node:20-alpine AS production
WORKDIR /app

ENV NODE_ENV=production

# Mise à jour des paquets de sécurité
RUN apk update && apk upgrade --no-cache

# Création d'un utilisateur non-root
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 nodejs

# Copie sélective depuis les stages précédents
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./

# Attribution des permissions
RUN chown -R nodejs:nodejs /app
USER nodejs

# Exposition du port standard
EXPOSE 3000

# Healthcheck HTTP pour Kubernetes
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"

# Démarrage de l'application
CMD ["node", "dist/index.js"]
```

## Explications ligne par ligne

### Stage 1 : Dépendances (`deps`)

| Instruction | Rationale |
| - | - |
| `COPY package*.json` avant le reste | Isole les manifests pour que Docker cache cette layer tant que les dépendances ne changent pas |
| `npm ci --omit=dev` | Installation reproductible et rapide, sans les outils de développement |
| `--ignore-scripts` | Empêche l'exécution de scripts post-install potentiellement malveillants |

### Stage 2 : Build (`build`)

| Instruction | Rationale |
| - | - |
| `npm ci` (toutes les deps) | TypeScript, Jest, Webpack et autres outils de build sont nécessaires ici |
| `COPY . .` après `npm ci` | Le code source change plus souvent que les dépendances : cette layer est reconstruite sans invalider le cache npm |
| `npm prune --omit=dev` | Réduction de la taille de `node_modules` avant copie vers la production |

### Stage 3 : Production (`production`)

| Instruction | Rationale |
| - | - |
| `apk update && apk upgrade` | Application des correctifs de sécurité Alpine au moment du build |
| `adduser --system --uid 1001` | Utilisateur dédié sans shell, sans home, minimisant la surface d'attaque |
| `COPY --from=deps` + `COPY --from=build` | Seuls les artefacts nécessaires transitent dans l'image finale : pas de source, pas de devDependencies |
| `USER nodejs` | Le processus ne tourne jamais en root, même si le conteneur est compromis |
| `HEALTHCHECK` | Kubernetes utilise cette sonde pour détecter automatiquement les conteneurs en détresse |

## Variantes par langage

**Node.js (par défaut)**

Le gabarit ci-dessus s'applique tel quel. Assurez-vous que votre `package.json` contient les scripts `build` et que le point d'entrée compilé est bien `dist/index.js`.

**Python**

```dockerfile theme={null}
# Stage 1 : Build
FROM python:3.11-alpine AS build
WORKDIR /app
COPY requirements.txt ./
RUN pip install --user --no-cache-dir -r requirements.txt
COPY . .

# Stage 2 : Production
FROM python:3.11-alpine AS production
WORKDIR /app
RUN adduser -D -u 1001 pythonuser
COPY --from=build /root/.local /home/pythonuser/.local
COPY --from=build /app ./
ENV PATH=/home/pythonuser/.local/bin:$PATH
USER pythonuser
EXPOSE 3000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3000"]
```

**Rust**

```dockerfile theme={null}
# Stage 1 : Build
FROM rust:1.75-alpine AS build
RUN apk add --no-cache musl-dev
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release && rm -rf src
COPY . .
RUN cargo build --release

# Stage 2 : Production (distroless)
FROM gcr.io/distroless/cc-debian12 AS production
WORKDIR /app
COPY --from=build /app/target/release/mon-app ./
USER nonroot:nonroot
EXPOSE 3000
CMD ["./mon-app"]
```

## Bonnes pratiques

> **Cache des layers**
>
> Copiez toujours les fichiers de dépendances (package.json, requirements.txt, Cargo.toml) avant le code source. Cela permet à Docker de réutiliser le cache des installations quand seul le code change.

> **Minimisation de l'image**
>
> L'image finale ne contient que le runtime et les artefacts compilés. Pas de sources, pas de git, pas de devDependencies. L'image passe typiquement de 1.2 Go à \~150 Mo.

> **Sécurité non-root**
>
> L'utilisateur `nodejs` (uid 1001) n'a pas les droits root. Même en cas d'exploitation d'une vulnérabilité dans l'application, l'attaquant est confiné.

> **Healthcheck natif**
>
> Le healthcheck HTTP intégré évite les dépendances externes (curl, wget) et fonctionne avec le runtime Node.js déjà présent.

> [!WARNING]
>
> Ne modifiez jamais l'ordre des stages ni les UID/GID sans synchronisation avec l'équipe DevOps. Les PodSecurityPolicies et les NetworkPolicies du cluster s'appuient sur ces identifiants.

> [!TIP]
>
> Pour les projets TypeScript, vérifiez que `tsconfig.json` produit bien une sortie dans `dist/`. Le `CMD` du Dockerfile attend `dist/index.js` comme point d'entrée.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.