Nous avons vu comment créer et lancer un conteneur, ainsi que construire une image avec un Dockerfile.
Maintenant, intéressons-nous à la persistance des données dans un conteneur via les volumes.
Rappel : chaque conteneur est basé sur une image dont les couches (layers) sont en lecture seule, et Docker utilise un Union File System (OverlayFS par exemple) pour appliquer une couche en écriture au-dessus de l’image.
- UnionFS : système de fichiers empilé.
- Les modifications écrites par le conteneur restent dans la couche la plus haute.
- Si on supprime le conteneur, ces modifications sont perdues, sauf si elles ont été externalisées dans un volume.
- Volumes nommés (Named Volumes)
- Gérés entièrement par Docker.
- Créés via
docker volume create monvolume
. - Montés par
-v monvolume:/chemin/dans/le/conteneur
.
- Bind mounts (dossier local)
- On spécifie un chemin local :
-v /home/user/data:/chemin/dans/le/conteneur
. - Permet de travailler directement avec les fichiers sur la machine hôte.
- On spécifie un chemin local :
- Volumes temporaires (Anonymous volumes)
- Créés automatiquement par Docker, sans nom spécifique.
Quand utiliser quel type de volume ?
- Named volumes : pour persister les données des applications en production (ex. : bases de données).
- Bind mounts : pour un environnement de développement (modifications locales visibles immédiatement).
- Anonymous volumes : pour des tests rapides ou des cas où la persistance n’est pas nécessaire.
- Créer un volume :
docker volume create monvolume
- Lister les volumes :
docker volume ls
- Inspecter un volume :
docker volume inspect monvolume
- Utiliser un volume :
docker run -v monvolume:/data ...
- Supprimer un volume :
docker volume rm monvolume
- Migrer un volume : utiliser un conteneur temporaire pour copier les données :
docker run --rm \ -v source_volume:/data1 \ -v target_volume:/data2 \ alpine sh -c "cp -r /data1/* /data2/"
- Pour protéger un bind mount en lecture seule :
-v /path:/containerpath:ro
- Créer un volume :
docker volume create myhtml
- Créer un fichier
index.html
localement :
<html>
<head><title>Encore un fichier HTML bidon</title></head>
<body>
<h1>Bravo Damien, mais on en a marre un peu non ?</h1>
</body>
</html>
- Lancer un conteneur avec le volume :
docker run -d \
--name volumetest \
-p 80:80 \
-v myhtml:/usr/share/nginx/html \
nginx:alpine
- Copier le fichier dans le volume :
docker cp index.html volumetest:/usr/share/nginx/html
- Modifier le fichier puis re-copiez le dans le volume.
- La page web a t-elle changé ?
- Tester la persistance :
- Supprimez et recréez le conteneur. La page est toujours accessible à
http://localhost
.
- Supprimez et recréez le conteneur. La page est toujours accessible à
- Créer un dossier local nommé
webcontent
avec unindex.html
:
<html>
<head><title>Encore un fichier HTML bidon</title></head>
<body>
<h1>Bravo Damien, mais on en a marre un peu non ?</h1>
</body>
</html>
- Lancer le conteneur avec le bind mount :
docker run -d \
--name bindtest \
-p 80:80 \
-v $(pwd)/webcontent:/usr/share/nginx/html \
nginx:alpine
- Modifier le fichier
index.html
local et rafraîchir la page web :
- Les changements sont visibles immédiatement.
- Lancer un conteneur MySQL avec un volume nommé :
docker run -d \
--name mysqltest \
-e MYSQL_ROOT_PASSWORD=root \
-v mysql_data:/var/lib/mysql \
mysql:5.7
NB : choisissez une version de MySQL compatible avec votre architecture et qui soit une version récente.
- Ajouter un conteneur Adminer pour gérer facilement la base de données :
docker run -d \
--name adminer \
--link mysqltest:db \
-p 8080:8080 \
adminer
- Le conteneur Adminer utilise le réseau Docker pour se connecter à MySQL via le nom du conteneur (
mysqltest
) et pour Adminer, l'alias pour MySQL estdb
. - Attention : l’option
--link
est obsolète, mais fonctionne encore. Nous verrons plus tard comment faire sans.
- Accéder à Adminer :
- Ouvrez un navigateur à l’adresse http://localhost:8080.
- Connectez-vous avec les informations suivantes :
- Serveur :
db
(le nom du conteneur MySQL). - Utilisateur :
root
. - Mot de passe :
root
. - Base de données : laissez vide (vous pouvez en créer une depuis Adminer).
- Serveur :
- Créer une table et insérer des données :
- Une fois connecté, créez une base de données appelée
testdb
. - Naviguez dans cette base de données et créez une table
users
avec les colonnes suivantes :id
(int, clé primaire, auto-incrémentée).name
(varchar).email
(varchar).
- Insérez quelques lignes dans la table via l’interface d’Adminer.
- Une fois connecté, créez une base de données appelée
- Vérifier la persistance des données :
- Supprimez le conteneur MySQL :
docker stop mysqltest
docker rm mysqltest
- Relancez un nouveau conteneur MySQL avec le même volume :
docker run -d \ --name mysqltest \ -e MYSQL_ROOT_PASSWORD=root \ -v mysql_data:/var/lib/mysql \ mysql:5.7
- Rafraîchissez Adminer à http://localhost:8080.
- Vérifiez que vos données dans la table
users
sont toujours présentes.
Profitez de ce TP pour installer Ghost, un CMS basé sur Node.js, avec une base de données MySQL. Le but est de prendre en main Ghost et de faire votre portfolio.
Allez sur l'image Ghost sur Docker Hub puis lisez la documentation pour savoir comment la lancer avec une base de données MySQL.
Indice :
docker run -d \
--name ghostcms \
-p ????:???? \
-e url=???? \
-e database__client=mysql \
-e database__connection__host=???? \
-e database__connection__user=???? \
-e database__connection__password=???? \
-e database__connection__database=???? \
--link ????:mysql \
-v ghost_content:/var/lib/ghost/content \
ghost:latest
Pensez à aller sur http://localhost:???/ghost/ pour configurer votre blog.