informatique:docker
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| informatique:docker [2023/11/23 09:33] – [Gestion des volumes] benoit | informatique:docker [2026/01/15 05:45] (Version actuelle) – benoit | ||
|---|---|---|---|
| Ligne 5: | Ligne 5: | ||
| * [[informatique: | * [[informatique: | ||
| * [[informatique: | * [[informatique: | ||
| + | * [[informatique: | ||
| + | * [[informatique: | ||
| + | * [[informatique: | ||
| + | * [[informatique: | ||
| + | * [[informatique: | ||
| + | * [[informatique: | ||
| Ligne 11: | Ligne 17: | ||
| - | ==== Type Volume ==== | ||
| - | Lister les volumes : | ||
| - | docker volume ls | ||
| - | Créer un volume nommé '' | ||
| - | docker volume create MyVolume | ||
| - | Ci-dessous pour démarrer un conteneur en utilisant le volume '' | ||
| - | docker run -d --name MyContainer -v MyVolume:/ | ||
| - | ou | ||
| - | docker run -d --name MyContainer --mount type=bind, | ||
| - | | ||
| - | | ||
| - | Pour identifier où sont stockées les données de '' | ||
| - | docker volume inspect MyVolume | ||
| - | Exemple de résultat attendu : | ||
| - | [ | ||
| - | { | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | } | ||
| - | ] | ||
| - | :!: Les données des volumes sont stockées dans le répertoire ''/ | ||
| - | Pour identifier les conteneurs qui utilisent le volume '' | ||
| - | docker ps -a --filter volume=MyVolume | ||
| - | Exemple de résultat attendu : | ||
| - | CONTAINER ID | ||
| - | b3f7ec23a377 | ||
| - | Pour supprimer le volume '' | ||
| - | docker volume rm MyVolume | ||
| - | :!: Remarque : Les conteneurs créés en utilisant le volume, doivent être arrêté et supprimé avant : | ||
| - | docker stop MyContainer | ||
| - | docker rm MyContainer | ||
| - | docker volume rm MyVolume | ||
| - | ==== Type Bind ==== | ||
| - | On peut aussi démarrer un conteneur en montant un dossier du système hôte dans un répertoire du conteneur. | ||
| - | Par exemple, ci-dessous on monte le dossier ''/ | ||
| - | docker run -d --name MyC2 --mount type=bind, | ||
| - | |||
| - | Pour inspecté le montage du conteneur : | ||
| - | docker inspect -f '{{ .Mounts }}' MyC2 | ||
| - | |||
| - | ==== Type TmpFs ==== | ||
| - | |||
| - | Pour démarrer une instance avec le dossier ''/ | ||
| - | |||
| - | docker run -d --name MyC3 --mount type=tmpfs, | ||
| - | |||
| - | |||
| - | ===== Utilisateurs et permissions ===== | ||
| - | |||
| - | :!: A COMPLETER | ||
| - | |||
| - | Pour lancer un conteneur avec un autre utilisateur : | ||
| - | docker run -d --name MyC1 -u benoit httpd | ||
| - | |||
| - | ===== Réseaux sous Docker ===== | ||
| - | |||
| - | Quelques commandes. | ||
| - | |||
| - | Pour lister les réseaux : | ||
| - | docker network ls | ||
| - | |||
| - | Exemple de résultat : | ||
| - | NETWORK ID | ||
| - | a5058156ace7 | ||
| - | 308d0f7c3659 | ||
| - | 499ff58d4934 | ||
| - | |||
| - | Pour avoir les détails sur les caractéristiques d'une des réseaux (par exemple le réseau Bridge) : | ||
| - | docker network inspect a5058156ace7 | ||
| - | |||
| - | |||
| - | ==== Mode Bridge (Par défaut) ==== | ||
| - | |||
| - | Par défaut Docker fonctionne en mode Bridge. Ci-dessous, quelques commandes pour comprendre le comportement. | ||
| - | |||
| - | L'IP locale 172.17.0.1/ | ||
| - | ip a show docker0 | ||
| - | |||
| - | Exemple de résultat : | ||
| - | 3: docker0: < | ||
| - | link/ether 02: | ||
| - | inet 172.17.0.1/ | ||
| - | | ||
| - | inet6 fe80:: | ||
| - | | ||
| - | |||
| - | |||
| - | Par exemple, démarrons un conteneur '' | ||
| - | docker run --name c1 -d httpd | ||
| - | |||
| - | Nous pouvons voir que par défaut ce conteneur écoute sur le port 80 : | ||
| - | docker ps | ||
| - | CONTAINER ID | ||
| - | d42852ccd99f | ||
| - | |||
| - | | ||
| - | Ci-dessous, nous récupérons l' | ||
| - | docker inspect -f ' | ||
| - | |||
| - | Résultat : | ||
| - | 172.17.0.2 map[80/ | ||
| - | |||
| - | Notre conteneur c1 a les caractéristiques suivantes : | ||
| - | * Son IP est **172.17.0.2** | ||
| - | * Il écoute sur le **port 80** | ||
| - | * Sa passerelle par défaut est **172.17.0.1** | ||
| - | | ||
| - | Notre hôte docker '' | ||
| - | telnet 172.17.0.2 80 | ||
| - | |||
| - | Trying 172.17.0.2... | ||
| - | Connected to 172.17.0.2. | ||
| - | Escape character is ' | ||
| - | |||
| - | get / | ||
| - | |||
| - | HTTP/1.1 400 Bad Request | ||
| - | Date: Mon, 20 Nov 2023 07:33:33 GMT | ||
| - | Server: Apache/ | ||
| - | Content-Length: | ||
| - | Connection: close | ||
| - | Content-Type: | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ | ||
| - | < | ||
| - | < | ||
| - | </p> | ||
| - | </ | ||
| - | Connection closed by foreign host. | ||
| - | |||
| - | Cependant, le port 80 du conteneur n'est accessible que par la machine hôte. Une machine externe, ne pourra pas interagir sur le port 80 de notre conteneur. Il faut donc publier le port 80 sur un port disponible de notre hôte. | ||
| - | |||
| - | Nous allons supprimer le conteneur et en créer un nouveau que nous allons publier sur le port 80 du conteneur sur le port 8080 de notre hôte : | ||
| - | docker rm -f c1 | ||
| - | docker run --name c1 -p 8080:80 -d httpd | ||
| - | |||
| - | Cette fois nous pouvons voir que notre conteneur écoute sur le port 80 et que celui-ci est publié sur le port 8080 de notre machine : | ||
| - | docker ps | ||
| - | CONTAINER ID | ||
| - | d3bda19ffc15 | ||
| - | |||
| - | |||
| - | Pour créer un réseau Bridge nommé '' | ||
| - | docker network create --driver=bridge --subnet=192.168.0.0/ | ||
| - | | ||
| - | on peut ajouter une option pour que l' | ||
| - | docker network create --driver=bridge --subnet=192.168.0.0/ | ||
| - | |||
| - | Pour lancer un conteneur qui utilisera ce réseau : | ||
| - | docker run -d --name c1 --network mynet0 httpd | ||
| - | |||
| - | On peut aussi connecter un conteneur déjà en fonctionnement d'un autre réseau ou réseau par défaut. | ||
| - | |||
| - | Ci-dessous, on va démarrer un conteneur dans le réseau par défaut, puis le connecter également à notre réseau '' | ||
| - | docker run -d --name c2 httpd | ||
| - | docker network connect mynet0 c2 | ||
| - | |||
| - | Le conteneur '' | ||
| - | docker inspect c2 | ||
| - | |||
| - | ==== Mode Host ==== | ||
| - | |||
| - | Le mode '' | ||
| - | |||
| - | On démarre de conteneur en mode host. | ||
| - | |||
| - | docker run --name c3 -d --network host httpd | ||
| - | |||
| - | Le port 80 de la machine écoutera directement sur l' | ||
| - | |||
| - | Sauf vraiment cas spécifique, | ||
| - | |||
| - | ===== Création d' | ||
| - | |||
| - | ==== Docker commit ==== | ||
| - | |||
| - | Permet de créer des images à partir d'un conteneur. Il est recommandé de l' | ||
| - | Par exemple dans les cas suivants : | ||
| - | * Snapshot ponctuel du conteneur | ||
| - | * Faire un fix rapide dans le conteneur mais non durable | ||
| - | * Tester et debugguer | ||
| - | |||
| - | Pour des modifications plus durable, il vaut mieux s' | ||
| - | |||
| - | Pour commencer démarrer un conteneur **debian** qui lance la commande '' | ||
| - | docker run -d --name c1 debian sleep infinity | ||
| - | |||
| - | On peut se connecter au conteneur, y apporter les modifications que l'on souhaite et le quitter, par exemple : | ||
| - | docker exec -ti c1 bash | ||
| - | echo " | ||
| - | ... | ||
| - | exit | ||
| - | |||
| - | On peut donc créer une image de l' | ||
| - | docker commit c1 myimage-c1: | ||
| - | |||
| - | Avec la commande... | ||
| - | docker image ls | ||
| - | |||
| - | ...On peut voir | ||
| - | REPOSITORY | ||
| - | myimage-c1 | ||
| - | debian | ||
| - | |||
| - | On peut de nouveau créer un nouveau conteneur à partir de cette image ainsi : | ||
| - | docker run -d --name c2 myimage-c1: | ||
| - | |||
| - | En listant les processus Docker en fonctionnement... | ||
| - | docker ps | ||
| - | |||
| - | ...On constate que les 2 conteneurs sont en fonctionnement avec la commande '' | ||
| - | CONTAINER ID | ||
| - | a9b8064f9bcb | ||
| - | 1600fa08b0a1 | ||
| - | |||
| - | :!: Pourtant le conteneur c2 n'a pas été lancé avec la commande '' | ||
| - | |||
| - | On peut ajouter d' | ||
| - | docker commit --message "mes commentaires" | ||
| - | |||
| - | On peut retrouver ces informations ainsi dans l' | ||
| - | docker inspect -f " | ||
| - | |||
| - | On peut lister l' | ||
| - | docker history myimage-c1: | ||
| - | | ||
| - | Exemple de résultat : | ||
| - | IMAGE CREATED | ||
| - | a1b6eff85cc8 | ||
| - | 0ce03c8a15ec | ||
| - | < | ||
| - | |||
| - | On peut ajouter des modifications/ | ||
| - | docker commit --change "ENV MYVAR=Benoit" | ||
| - | |||
| - | Lorsque l'on créé un conteneur à partir de cette nouvelle image on constate que la variable est bien active : | ||
| - | docker run -d --name c3 myimage-c1: | ||
| - | docker exec c3 env | ||
| - | |||
| - | Résultat : | ||
| - | PATH=/ | ||
| - | HOSTNAME=1f8770a8bb5b | ||
| - | MYVAR=Benoit | ||
| - | HOME=/root | ||
| - | |||
| - | ==== Dockerfile ==== | ||
| - | |||
| - | L' | ||
| - | |||
| - | L' | ||
| - | |||
| - | === Bonnes pratiques === | ||
| - | |||
| - | Les bonnes pratiques pour créer une image sont les suivantes : | ||
| - | |||
| - | * **Utiliser une image de base fiable et légère** | ||
| - | * Vérifier la source de la registry sur Docker Hub par exemple. | ||
| - | * Eviter d' | ||
| - | * Spécifier le TAG de l' | ||
| - | * Ou bien utiliser la référence '' | ||
| - | |||
| - | |||
| - | * **Garder une image légère** | ||
| - | * Grouper les commandes d' | ||
| - | * Supprimer les caches d' | ||
| - | * Exemple: '' | ||
| - | * Eviter d' | ||
| - | * Supprimer les paquets non requis | ||
| - | * Faire un build multi-stage | ||
| - | |||
| - | * **Créer un dossier dédié pour y préparer les fichiers, app à copier dans notre image** | ||
| - | * Utiliser une fichier '' | ||
| - | * Utiliser l' | ||
| - | * Utiliser '' | ||
| - | * Attention de ne pas laisser des fichiers confidentiels | ||
| - | * Eviter par exemple : '' | ||
| - | |||
| - | * **Bien penser l' | ||
| - | * Créer un utilisateur par défaut pour éviter de faire tourner l' | ||
| - | * Penser à basculer sur l' | ||
| - | * Penser à utiliser des variables d' | ||
| - | * Penser à définir le répertoire de travail par défaut du conteneur '' | ||
| - | |||
| - | * **Versionner les éléments installés** | ||
| - | |||
| - | * **Eviter de créer une image contenant plusieurs brique applicatives. | ||
| - | * Exemple : Application + Base de données | ||
| - | |||
| - | * **Identifier le " | ||
| - | |||
| - | |||
| - | === Création du Dockerfile === | ||
| - | |||
| - | En exemple, Nous allons simplement créer une image contenant un serveur Web apache basé sur une image Debian. | ||
| - | |||
| - | Pour commencer, créer un dossier de travail et aller dedans : | ||
| - | mkdir myapp | ||
| - | cd myapp | ||
| - | |||
| - | Créer dans le dossier créer un fichier ' | ||
| - | Dockerfile | ||
| - | |||
| - | On va créer un dossier '' | ||
| - | mkdir app | ||
| - | echo " | ||
| - | |||
| - | Créer le Dockerfile suivant : | ||
| - | vim Dockerfile | ||
| - | |||
| - | Contenu en exemple : | ||
| - | # Source pour l' | ||
| - | FROM debian: | ||
| - | # On peut également cibler l' | ||
| - | #FROM debian@sha256: | ||
| - | | ||
| - | # Labels pour identifier notre image | ||
| - | LABEL version=1.0 | ||
| - | LABEL auteur=Benoit | ||
| - | | ||
| - | # On défini quelque variable d' | ||
| - | ENV APP_ENV=" | ||
| - | ENV APP_NAME=" | ||
| - | ENV APP_VER=" | ||
| - | | ||
| - | # On définir des variable à utilsier dans le Dockerfile | ||
| - | ARG APP_USER=" | ||
| - | | ||
| - | # Création de l' | ||
| - | RUN adduser ${APP_USER} | ||
| - | | ||
| - | # Intallation des paquetages requis | ||
| - | # A noter qu'on lance l' | ||
| - | RUN apt update && apt install -y apache2 && apt clean && rm -rf / | ||
| - | |||
| - | # On execute les prerequis pour lancer notre serveur Apache2 | ||
| - | RUN mkdir -p / | ||
| - | | ||
| - | # On lance apache2 | ||
| - | CMD ["/ | ||
| - | | ||
| - | # Répertoire de travail de l'App | ||
| - | WORKDIR / | ||
| - | | ||
| - | # Ci-dessous la directive pour faire tourner l' | ||
| - | #USER ${APP_USER} | ||
| - | | ||
| - | # On copie les fichiers locaux sur le WORKDIR du conteneur | ||
| - | COPY app/* . | ||
| - | # Exemple ci-dessous en spécifiant les permissions | ||
| - | #COPY --chown=${APP_USER} app/* . | ||
| - | | ||
| - | # On expose le port 80 | ||
| - | EXPOSE 80 | ||
| - | |||
| - | |||
| - | |||
| - | Lancer le build de l' | ||
| - | docker build -t webapp:v1 . | ||
| - | | ||
| - | Pour lancer un conteneur à partir de notre image : | ||
| - | docker run -d --name c1 -p 8080:80 webapp:v1 | ||
| - | |||
| - | === Exemple de Dockerfile multi-stages === | ||
| - | |||
| - | Le build multistage permet de reprendre des éléments d'une autre image pour créer l' | ||
| - | # Build 0 | ||
| - | FROM debian: | ||
| - | # On crée un fichier | ||
| - | RUN echo " | ||
| - | | ||
| - | # Build 1 | ||
| - | # On peut définir un alias par exemple b1 pour la source | ||
| - | FROM debian: | ||
| - | # On crée le fichier /var/toto.2 | ||
| - | RUN echo " | ||
| - | # On recopie à partir du build 0 le fichier /var/toto.1 que l'on copie dans / | ||
| - | COPY --from=0 /var/toto.1 / | ||
| - | | ||
| - | # Build 2 | ||
| - | FROM debian: | ||
| - | # On crée le fichier /var/toto.3 | ||
| - | RUN echo " | ||
| - | # On recopie à partir du build 1 le fichier /var/toto.2 que l'on copie dans / en indiquant l' | ||
| - | COPY --from=b1 /var/toto.2 / | ||
| - | # On peut aussi copier un fichier depuis une image existante | ||
| - | COPY --from=httpd: | ||
| - | |||
| - | On final dans ce build on retrouvera uniquement les fichiers suivants : | ||
| - | * ''/ | ||
| - | * ''/ | ||
| - | * ''/ | ||
| - | |||
| - | === Exemple de Dockerfile multi-stages conditionnel === | ||
| - | |||
| - | Le Dockerfile : | ||
| - | |||
| - | # DECLARATION VARIABLE POUR LE BUILD AVEC VALEUR PAR DEFAUT | ||
| - | ARG TYPE=development | ||
| - | | ||
| - | # IMAGE DE BASE | ||
| - | FROM debian: | ||
| - | RUN echo " | ||
| - | | ||
| - | # IMAGE AVEC LES ELEMENTS DE DEV | ||
| - | FROM base AS branch-version-development | ||
| - | # Tous les élements requis pour l' | ||
| - | RUN echo " | ||
| - | ENV ENV=development | ||
| - | | ||
| - | # IMAGE AVEC LES ELEMENTS DE PROD | ||
| - | FROM base AS branch-version-production | ||
| - | # Tous les élements requis pour l' | ||
| - | RUN echo " | ||
| - | ENV ENV=production | ||
| - | | ||
| - | # IMAGE AVEC LES ELEMENTS DE DEV OU PROD EN FONCTION DE LA VARIABLE TYPE | ||
| - | FROM branch-version-${TYPE} AS final | ||
| - | UN echo " | ||
| - | |||
| - | Si on souhaite créer une image avec les éléments de dev : | ||
| - | docker build -t myapp:v1 --build-arg TYPE=development . | ||
| - | |||
| - | Et pour la prod : | ||
| - | docker build -t myapp:v1 --build-arg TYPE=production . | ||
| - | |||
| - | On peut aussi lancer le build de la base uniquement : | ||
| - | docker build -t myapp:v1 --target base | ||
informatique/docker.1700732010.txt.gz · Dernière modification : de benoit
