feat: docs
CI / 🔍 Lint & Type Check (push) Successful in 2m11s
CI / 🐳 Build & Push Image (push) Successful in 1m16s

This commit is contained in:
2026-07-17 16:15:54 +02:00
parent 0c2f42b4a3
commit 1542a991b9
38 changed files with 6366 additions and 19 deletions
@@ -0,0 +1,74 @@
---
title: Du code au conteneur
description: Le cycle code, Dockerfile, build, image, run et conteneur.
---
Le cycle de vie complet suit toujours le même enchaînement :
```text
code de l'application + Dockerfile
│ docker build
image
│ docker run
conteneur
```
<Steps>
<Step>
### Versionner le code et le Dockerfile
Le code et sa recette de construction vivent ensemble dans le dépôt.
</Step>
<Step>
### Construire l'image
`docker build` lit le Dockerfile et exécute chaque instruction. Le résultat est une image figée et taguée.
```bash
docker build -t mon-app/backend:1.4.0 .
```
</Step>
<Step>
### Instancier l'image
`docker run`, ou `docker compose up`, lance un conteneur qui exécute la commande de démarrage.
```bash
docker run --rm mon-app/backend:1.4.0
```
</Step>
</Steps>
## Build et run sont deux opérations différentes
Le **build** produit une image, normalement une fois par version. Le **run** lance autant de conteneurs que nécessaire à partir de cette image.
## L'image reste immuable
Un conteneur peut écrire dans son propre système de fichiers. Ces écritures disparaissent lorsque le conteneur est détruit, sauf lorsqu'elles sont stockées dans un volume.
L'image d'origine, elle, ne change jamais.
## Le rôle de CMD
`CMD` indique le processus principal lancé au démarrage :
```dockerfile
CMD ["node", "dist/src/main"]
```
Dans cet exemple, le conteneur est le processus Node. Si ce processus s'arrête, le conteneur s'arrête.
<Callout title="Conséquence" type="info">
Une image constitue l'artefact à livrer. Le conteneur n'est que son instance en cours d'exécution, avec une configuration et un état temporaires.
</Callout>
@@ -0,0 +1,70 @@
---
title: Images Docker
description: Utiliser une image existante ou construire une image adaptée à son application.
---
## Une image est un template en lecture seule
Une image regroupe le userspace, l'application et sa configuration de démarrage. Elle est figée : on ne la modifie pas après sa construction, on l'instancie sous la forme d'un conteneur.
Une même image peut servir à lancer plusieurs conteneurs.
## Des couches partagées
Une image est composée de couches, ou *layers*. Chaque instruction de construction ajoute une couche. Docker peut mettre ces couches en cache et les partager entre plusieurs images.
Si dix images utilisent `node:25-slim` comme base, cette couche n'est téléchargée et stockée qu'une seule fois.
## Utiliser une image existante
Docker Hub et d'autres registries, comme GHCR, proposent des images prêtes à l'emploi. Pour un service standard, il suffit généralement d'utiliser l'image officielle :
```yaml
services:
postgres:
image: postgres:16-alpine
minio:
image: minio/minio:latest
mailpit:
image: axllent/mailpit:latest
nginx:
image: nginx:1.27-alpine
```
Le suffixe après les deux-points est le **tag**. Par exemple, `postgres:16-alpine` désigne PostgreSQL 16 sur une base Alpine Linux minimale.
<Callout title="Épingler les versions" type="warning">
Préfère un tag précis comme 16-alpine ou 1.27-alpine à latest. Le résultat sera plus prévisible et les builds plus reproductibles.
</Callout>
## Construire une image custom
Le code de ton frontend ou de ton backend est unique. Il faut donc écrire un Dockerfile qui part d'une image existante et ajoute l'application :
```dockerfile
FROM node:25-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["node", "dist/src/main"]
```
L'instruction `FROM` exprime l'héritage : l'image de l'application réutilise `node:25-slim`, puis ajoute ses propres couches.
## Choisir entre image et build
| Besoin | Choix |
| --- | --- |
| Base de données ou proxy standard | Image officielle via `image:` |
| Application développée par l'équipe | Image custom via un Dockerfile |
| Outil tiers avec configuration légère | Image officielle + variables et volumes |
| Runtime spécifique et code métier | Dockerfile custom |
+5
View File
@@ -0,0 +1,5 @@
{
"title": "Images et builds",
"description": "Construire des images reproductibles et efficaces",
"pages": ["images-docker", "cycle-de-vie", "multi-stage-et-cache"]
}
@@ -0,0 +1,90 @@
---
title: Multi-stage et cache de build
description: Accélérer les builds et réduire la taille de l'image finale.
---
## Le modèle de couches
Chaque instruction d'un Dockerfile produit une couche. Au prochain build, Docker réutilise une couche mise en cache tant que ses entrées n'ont pas changé.
<Callout title="Règle du cache" type="warning">
Le cache fonctionne comme un préfixe : dès qu'une couche est invalidée, toutes les couches suivantes doivent être reconstruites.
</Callout>
## Ce qui invalide une couche
| Instruction | Le cache saute si… |
| --- | --- |
| `FROM node:25-slim` | Le digest de l'image de base change |
| `COPY package.json ./` | Le contenu du fichier copié change |
| `RUN npm ci` | La commande ou une couche précédente change |
| `COPY . .` | N'importe quel fichier du contexte change |
`COPY` compare le contenu, pas seulement la date. Avec `COPY . .`, le moindre changement dans le contexte invalide cette couche.
## Ordonner du plus stable au plus volatil
```dockerfile
FROM node:25-slim AS builder
WORKDIR /app
# Les manifestes changent rarement
COPY package.json package-lock.json ./
RUN npm ci
# Le code change souvent
COPY . .
RUN npm run build
```
Si un fichier TypeScript change, les couches `COPY package.json` et `RUN npm ci` restent en cache. Seules la copie du code et la compilation sont rejouées.
À l'inverse, placer `COPY . .` avant `npm ci` provoquerait une réinstallation complète des dépendances à chaque changement de code.
## Stabiliser le contexte avec .dockerignore
```text
node_modules
dist
.git
*.log
```
Sans ce fichier, des dossiers locaux volumineux peuvent être envoyés au daemon et invalider le cache inutilement.
## Séparer la compilation du runtime
Un build multi-stage utilise plusieurs instructions `FROM`. Le premier stage contient les outils de compilation ; le second repart d'une image propre et ne récupère que le résultat.
```dockerfile
# Stage 1 - builder
FROM node:25-slim AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2 - runtime
FROM node:25-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
CMD ["node", "dist/src/main"]
```
## Deux bénéfices distincts
| Bénéfice | Explication |
| --- | --- |
| Image finale plus petite | Les sources, les caches et l'outillage du builder ne sont pas copiés dans le runtime. |
| Caches séparés | Le stage de build conserve son cache de dépendances ; le stage final ne change que si les artefacts changent. |
<Callout title="Aller plus loin" type="idea">
Copier node_modules depuis le builder embarque aussi les devDependencies. Pour une image plus légère, le stage final peut exécuter un npm ci --omit=dev dédié.
</Callout>