Outils pour utilisateurs

Outils du site


informatique:devops:docker

Docker

Je ne vais pas reprendre toutes les infos qu'on peut retrouver sur internet (cf. Docker#voir_aussi|le § Voir aussi), notamment sur la page docker de la doc Ubuntu et dans les livres, mais juste quelques points qu'il me semble important de retenir:

Network

À l'installation de docker, trois réseaux sont créer dont le réseau bridge. Il est important de noter qu'il faut créer un réseau bridge pour relier des conteneurs ayant besoins de communiquer. Comme précisé dans le livre 1), cela évite que tous les conteneurs soient reliés et permet à ceux qui sont connecté à un même bridge de le faire avec leur nom grâce au DNS intégré de docker.
Plus d'infos sur : https://docs.docker.com/network/host/ et https://docs.docker.com/network/network-tutorial-host/

(si on veut accéder au host) : https://stackoverflow.com/a/61480668/6614155https://stackoverflow.com/questions/57500887/how-to-access-host-mysql-server-in-a-docker-container

Dockefile

Dans le principe, un seul FROM par Dockerfile (même si on peut en mettre plusieurs, cf. dockefile_pour_dev_et_prod)

un seul ENTRYPOINT et un seul CMD

ENTRYPOINT ["/bin/ping","-c","5"]
CMD ["localhost"]

exécutera un ping localhost sauf si on surcharge le CMD, par exemple avec un

docker run ping-conteneur monSousDomaine.monDomaine.fr

qui équivaudra à un ping monSousDomaine.monDomaine.fr

EXPOSE juste à fin de documentation, pour faire connaître les ports exposés, c'est ce qui est affiché dans la colonne PORTS lors d'un

docker container ls
STATUS                    PORTS                    NAMES
Up 2 seconds              0.0.0.0:5433->5432/tcp   db-postgres

.
En pratique, c'est l'exécution du

 docker run -p 8080:80

qui réalise l'exposition

ADD permet de définir une source URL
décompresse les archives lors de la copie dans le conteneur
sinon préférer
COPY

Si on fait un conteneur pour des tests, il est à noter qu'un conteneur sans processus qui tourne est arrêté. Pour éviter cela on peut ajouter
ENTRYPOINT ping localhost
#ou
ENTRYPOINT tail -f /dev/null

Variables

cf. https://docs.docker.com/engine/reference/builder/#arg

On peut prévoir des variables avec le mot clé ARG :

ARG userid=1001
RUN chown -R $userid /var/www

La valeur prédéfinie n'est pas requise.
Cette valeur peut-être (sera généralement) définie lors du build :

docker build --name mon-image --build-arg userid=1000 

Ces variables ne persistent pas dans l'image.
Si on veut des variables persistante, on peut utiliser le mot clé ENV :

ENV version=1.0.0

On peut facilement lister les variables d'une instance docker :

docker exec nom_du_conteneur env

docker-compose

Ce fichier permet de regrouper les définitions de plusieurs containers
voir aussi la page dédié : Docker-compose

les variables d'environnement peuvent être défini dans le fichier .env situé dans le même répertoire que le docker-compose.yml

Gestion des images/volumes… sur la VM

Pour éviter d'être rappelé à l'ordre par les admin-sys,

docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              2                   2                   820MB               0B (0%)
Containers          2                   2                   1.413MB             0B (0%)
Local Volumes       2                   2                   12.92GB             0B (0%)
Build Cache         0                   0                   0B                  0

Comme on voit ci-dessus, 0B est récupérable car le(s) volume(s) est(sont) utilisé(s) par le conteneur registry qu'il faut arrêter/supprimer pour pouvoir récupérer l'espace.
Pour arriver à supprimer ces 13GB, j'ai dû arrêter les containers (docker stop …) puis un

docker volume prune

Autre cas, c'est les Images qui prennent de la place, exemple : SIZE: 11.36GB dont RECLAIMABLE: 8.344GB (73%), je lance alors 2) :

docker image prune -a

qui m'en récupère Total reclaimed space: 6.836GB

En fait, il est important de bien définir les volumes entre le host et les conteneurs. En effet, des logs trop gros (virtualisation artefacts-v2) ou fichiers temporaires un peu conséquents peuvent entraîner une dérive de la taille des conteneurs. Cela se traduit par une augmentation du répertoire /var/lib/docker/overlay2. En ajoutant les volumes, cela permet plus facilement d'effacer manuellement ou automatiquement avec un CRON les fichiers problématiques 3)

Travailler avec le(les) conteneur(s) actif(s)

Quels sont les conteneurs qui s'exécutent, récupérer son(leurs) identifiant:

docker ps

Se connecter à un conteneur lancé en démon (-d)

docker exec -it <docker-id> /bin/bash

Connaître le(s) volume(s) monté(s):

docker inspect -f "{{ .Mounts }}" <container name or id>

Voir les logs comme tail -f :

docker logs -f --tail 10 container_name

Récupérer le hash de l'image ayant servie à instancier un conteneur, notamment pour changer le tag de l'image pour bien l'identifier et la conserver avant de pousser un changement majeur (mise à niveau/changement de framework… laravel6→laravel10/bootstrap→tailwind) :

docker inspect --format='{{.Name}} {{.Image}}' $(docker ps -aq)

Reproduire en local un serveur

Du bon usage de docker save vs docker export: https://stackoverflow.com/a/33632669/6614155
en résumé: save : multi-layers et métadatas…, export: un seurl layer, pas de métadatas, ni USER EXPOSE RUN…

# sur le serveur:
docker save save myimage:latest | gzip > myimage_latest.tar.gz
# sur le poste de dév en local:
docker load …

Dockefile pour dev et prod

Il est possible de construire différemment une image selon qu'on est à l'étape de développement, test/debug… ou de production, pour faire cela, dans le Dockerfile, on écrit par exemple :

FROM php:7.4-fpm-alpine as app-build
…
FROM app-build as development
 
CMD php -S 0.0.0.0:80 -t public
 
FROM app-build as production
…

et on construit en utilisant l'option –target alias, dans notre exemple, pour développer4) :

docker build --target development

ou via docker-compose,
avec lequel on peut définir un service par cible, banadora-dev avec target: developement et banadora-prod avec target: production

tags

Lorsqu'on récupère une image, sauf à spécifier une version exacte, on va plutôt récupérer (tirer/pull) une version comme par exemple php:8-fpm-alpine
Entre l'étape de développement et celle de déploiement, cette image avec cette référence peut avoir bien évoluée… exemple la php:8-fpm-alpine que j'ai initialement chargée pour mon dev est la php 8.1.6. Lors du build sur une autre machine, c'est la 8.1.11 qui est récupérée.

La bonne pratique est de spécifier une version précise afin d'éviter d'une machine (dev) à une autre (prod ou autre dev) de se retrouver avec des versions différentes

Avant de déployer, aussi pour des raisons de sécurité (le docker hub affiche d'ailleurs les vulnérabilités), il peut donc être judicieux de recharger la dernière version.

docker pull php:8-fpm-alpine

Si on veut néanmoins conserver l’ancienne, on peut la re-taguer (son tag sera passé à <none>) avec une commande du type (ici php est le nom de l'image et 8.1… l'intitulé du tag) :

docker tag bdaaed87c005 php:8.1.6-fpm-alpine

Sécurité

Voir aussi

1)
Docker|Cloux Pierre-Yves, Thomas Garlot et Johann Kohler, Docker: pratique des architectures à base de conteneurs, sans lieu, 2019.
informatique/devops/docker.txt · Dernière modification : 2024/03/27 15:59 de bertrand