Composition de Docker
---------------------

Docker est une suite d'outils de haut niveau, permettant d'utiliser des
*conteneurs*. Le projet en lui-même utilise de nombreuses dépendances,
originellement développées par l'entreprise Docker Inc., puis laissé dans le
domaine public lors des efforts de standardisation en 2015.

Commençons par planter le décor, en détaillant les principes de base de Docker.

### Séparation des compétences

Le projet s'article autour d'un daemon lancé au démarrage de la machine, avec
lequel on interagit via un client (le programme `docker`). La communication
entre le daemon et le client s'effectuant sur une API REST généralement au
travers d'une socket.

::::: {.more}

Tous les programmes d'exécution de conteneurs n'utilisent pas une architecture
avec un daemon et un client. `podman` que l'on peut généralement substituer à
Docker n'emploie pas de daemon. Chaque utilisateur de la machine peut donc
disposer de ses propres conteneurs, sans interférer avec ceux de ses voisins.

D'un point de vue de la sécurité, le daemon Docker est exécuté en tant que
super-utilisateur. C'est sur ce daemon que repose la sécurité de la machine, ce
qui peut être beaucoup de responsabilité. Gardez en tête que le modèle
d'exécution de Docker n'est pas unique. Nous avons le choix.

:::::

Le processus client peut d'ailleurs ne pas être sur la même machine qui exécute
effectivement les conteneurs.[^dockermachine]
C'est ce qu'il se passe lorsqu'on utilise Docker sur Windows ou macOS :
une machine virtuelle Linux est lancée parallèlement au système de base et
chaque commande `docker` tapée est passée au daemon dans la machine virtuelle.

[^dockermachine]: Il suffit de modifier la variable d'environnement
    `DOCKER_HOST` ou de passer le paramètre `-H` suivi de l'URL de la socket à
    `docker`. Voir aussi : <https://docs.docker.com/machine/overview/>


### Les images Docker

Comme nous l'avons vu en introduction, les images sont un moyen de récupérer
facilement un environnement d'exécution complet, prêt à l'emploi. Une image
Docker donc est un système de fichiers en lecture seule.

Une image peut, par exemple, contenir :

* un système Ubuntu opérationnel,
* le programme `busybox`,
* votre site web personnel, prêt à l'emploi,
* ...

Les images sont utilisées comme **modèle** qui sera ensuite dupliqué à chaque
fois que l'on démarrera un nouveau conteneur.

Il y a deux méthodes pour obtenir des images Docker : soit les construire avec
les outils fournis, soit les récupérer depuis un registre.

Lorsque vous ne précisez pas l'adresse d'un registre, Docker va aller chercher
sur le [Docker Hub](https://hub.docker.com/). C'est le registre utilisé par
défaut.


### Les plugins Docker

L'architecture de Docker est devenue très modulable. Le projet est parti dans
de nombreuses directions, chacun voulant tirer la couverture vers soit, et
l'équipe maintenant le projet a parfois eu du mal à arbitrer les bonnes choses
à ajouter ou non au projet.

Afin de palier aux besoins complémentaires, parfois accessoires, parfois
salvateurs, un système de plugins a été intégré. Il permet d'appeler d'autres
programmes comme s'il s'agissait de composant de Docker.

Certains plugins ajoutent des options à la ligne de commande (`docker-compose`,
`docker-scan`, `docker-buildx` ...). D'autres ajoutent des typologies de
réseaux, de gestion du stockage ou ajoutent de l'authentification.

Pour ajouter un plugin à Docker, il suffit de l'ajouter dans un sous-dossier de
`/usr/lib/docker/cli-plugins` pour qu'il soit accessible à tous les
utilisateurs de notre machine ou dans `$HOME/.docker/` si l'on veut l'installer
seulement pour nous.

Par exemple, les plugins ajoutant des commandes iront dans
`$HOME/.docker/cli-plugins`. Par exemple, si l'on souhaite pouvoir disposer de
la commande `docker compose`, on téléchargera le plugin vers l'emplacement :
`$HOME/.docker/cli-plugins/docker-compose`.

Plus récemment, de nouveaux plugins ont vu le jour et se basent directement sur
des conteneurs que l'on peut télécharger depuis un registre d'images.
