feat: docs
This commit is contained in:
@@ -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 |
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user