## Qu'est-ce qu'un Dockerfile ?
Un Dockerfile est un fichier déclaratif utilisé par Docker pour automatiser la création d’images de conteneurs personnalisées via une suite d’instructions exécutées successivement.
> [!info] À savoir ! <span style="font-weight: normal; color: var(--text-normal)">Un Dockerfile sert à créer une image. Un conteneur est une instance de cette image en cours d’exécution</span>
## Cas d'usages
Si vous réalisez des CTF, des pentests ou des analyses forensics, vous savez que Kali Linux est une distribution avec de nombreux outils, mais qu'elle est très lourde. L'utilisation de Docker vous permet de l'exécuter dans un environnement minimal sans déployer une VM complète à chaque fois.
Par exemple la commande suivante permet d'exécuter un conteneur Kali Linux allégé :
```
docker run -it --rm -v .:/wdir kalilinux/kali-rolling
```
- `-it` lance le conteneur en mode interactif
- `--rm` supprime automatiquement le conteneur et les volumes anonymes associés après la sortie
- `-v .:/wdir` monte le dossier de travail actuel dans le conteneur sous `/wdir`
> [!warning] Rappel ! <span style="font-weight: normal; color: var(--text-normal)">Privilégiez l'utilisation de l'image officielle mise à disposition par Kali sur le Docker Hub : `kalilinux/kali-rolling`.</span>
Le problème est qu'à chaque démarrage d'un nouveau conteneur Kali, vous devez réinstaller vos outils préférés `nmap`, `john`, `sha256sum`, etc. et les outils spécifiques au CTF.
Il est fastidieux de refaire systématiquement les configurations de base (par exemple `apt update` ou installation d'outils `nmap`, `tcpdump`, `vim`, etc.). C'est ici qu'intervient un Dockerfile !
## Exemple de Dockerfile basique
Nous allons créer une nouvelle image personnalisée qui sera utilisée dans le cadre de la création d'environnements de test jetables.
### Préparer un fichier Dockerfile
> [!info] À savoir ! <span style="font-weight: normal; color: var(--text-normal)">Le nom `Dockerfile` est imposé par la convention Docker. Le fichier doit s’appeler `Dockerfile`, avec un `D` majuscule et sans extension (ni `.yml`, ni autre). </span>
Dans cette démonstration, je vais créer un dossier `kali-custom` et ajouter le fichier `Dockerfile` suivant :
```Dockerfile
# Image de base
FROM kalilinux/kali-rolling
# Met à jour la liste des paquets et installe les outils nécessaires
# --no-install-recommends permet de garder une image légère
# Nettoyage d'apt pour réduire la taille de l’image
RUN apt update && \
apt install -y --no-install-recommends nmap tcpdump vim && \
apt clean && \
rm -rf /var/lib/apt/lists/*
# Dossier de travail
WORKDIR /root
# Commande par défaut
CMD ["/bin/bash"]
```
### Build de l’image et exécution
Un build est le **processus** de création d'une image Docker. Ouvrir un terminal et se positionner `.\kali-custom` puis construire une image `kali-custom` avec la commande :
```powershell
docker build -t kali-custom .
```
> [!info] À savoir ! <span style="font-weight: normal; color: var(--text-normal)">Quand vous lancez `docker build`, Docker lit le `Dockerfile`, exécute chaque instruction (`FROM`, `RUN`, `COPY`, etc.) et crée l'image `kali-custom`.</span>
![[_asset-tuto-dockerfile.gif]]
Une fois l'image personnalisée créée, vous pouvez lancer un nouveau conteneur sur cette base :
```docker
docker run -it --rm kali-custom
```
Vous pouvez constater que les applications sont bien préinstallées, par exemple `vim`
![[_asset-tuto-dockerfile-1.gif]]
## Pour aller plus loin
### Bonnes pratiques Dockerfile
- Ajouter uniquement les outils nécessaires
- Nettoyer le cache APT (`apt clean` et suppression de `/var/lib/apt/lists`)
- Ne pas installer les paquets recommandés (`--no-install-recommends`)
- Éviter `apt upgrade -y` (non reproductible car chaque nouvelle image est différente)
- Fusionner les instructions `RUN` pour limiter le nombre de couches
- Spécifier un tag d’image (éviter `latest`) pour garantir la reproductibilité des environnements
- Utiliser un fichier `.dockerignore` pour exclure les fichiers inutiles
- Privilégier `COPY` plutôt que `ADD`
- Ordonner les instructions pour optimiser le cache Docker
- Exécuter les conteneurs avec un utilisateur non root (voir [[kb-dockerfile-non-root|exemple]])
### Structure recommandée
Pour organiser vos fichiers Dockerfile la structure typique recommandée est :
```
mon-projet/
├── Dockerfile
├── app/
├── requirements.txt
```
### Multi-Dockerfile
Il est possible d'avoir plusieurs Dockerfile dans le même dossier à condition d'utiliser l'option `-f` qui permet de spécifier le nom du fichier. Par exemple `Dockerfile.ctf`, `Dockerfile.pentests`, `Dockerfile.forensics` :
```
docker build -f Dockerfile.ctf -t kali-ctf .
```
## Conclusion
Un Dockerfile est un outil puissant qui permet de créer des environnements reproductibles, que ce soit pour des usages temporaires (tests, CTF) ou en production. L’objectif est de construire des images utiles, mais aussi minimales, ciblées sur un besoin précis et optimisées en taille.