Docker/Version imprimable

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche
Docker (container engine) logo.svg
Nuvola-inspired File Icons for MediaWiki-fileicon-ps.png

Ceci est la version imprimable de Docker.

  • Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
  • Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
  • Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.


Docker

Une version à jour et éditable de ce livre est disponible sur Wikilivres,
une bibliothèque de livres pédagogiques, à l'URL :
https://fr.wikibooks.org/wiki/Docker

Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la Licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans Texte de dernière page de couverture. Une copie de cette licence est incluse dans l'annexe nommée « Licence de documentation libre GNU ».

Sections

Introduction

Principe[modifier | modifier le wikicode]

Docker est un logiciel libre conçu pour lancer des applications dans des conteneurs logiciels. Ces conteneurs sont plus légers en ressources que les machines virtuelles car ils partagent leur noyau.

Différence entre un conteneur et une VM.
Docker sur Linux

Images et conteneurs[modifier | modifier le wikicode]

Les conteneurs sont construis à partir d'images qui partages leur couches en différentiel[1].

Docker met de plus à disposition un hub pour partager des images : https://hub.docker.com/. On y trouve par exemple celles permettant de faire tourner un site en MediaWiki : https://hub.docker.com/_/mediawiki.

Installation[modifier | modifier le wikicode]

Il existe plusieurs versions de Docker[2] :

  • Docker CE (community engine) : gratuit. Idéal sur un PC.
  • Docker EE (enterprise engine) : version payante certifiée, plutôt pour les serveurs.
  • Docker Enterprise : payant et dispose d'outils supplémentaires, par exemple pour gérer les images et les conteneurs.

Une fois installé, la commande suivante doit fonctionner : docker --version.

Linux[modifier | modifier le wikicode]

En 2019 on trouve des binaires pour les distributions de Linux suivantes : CentOS, Debian, Fedora et Ubuntu[3].

Après installation, le daemon Docker se lancera à chaque démarrage avec la possibilité de remonter certains conteneurs automatiquement[4].

MacOS[modifier | modifier le wikicode]

A télécharger sur https://docs.docker.com/docker-for-mac/install/.

Windows[modifier | modifier le wikicode]

Uniquement pour les versions pro, car Hyper-V est nécessaire. A télécharger sur https://docs.docker.com/docker-for-windows/install/.

Une interface graphique de gestion de conteneur nommée Kitematic[5] peut être intégrée dans un deuxième temps.

Logo Toute désinstallation de Docker supprimera les images construites sur le poste, et pourra donc occasionner de longs téléchargements après réinstallation et relance.


hosts[modifier | modifier le wikicode]

Sur Windows, Docker Desktop modifie le fichier hosts en ajoutant :

# Added by Docker Desktop
192.168.1.20 host.docker.internal
192.168.1.20 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section

WSL[modifier | modifier le wikicode]

Anciennement baptisé Tech Preview, Docker Desktop WSL 2 Backend utilise Windows Subsystem for Linux pour optimiser les performances de Docker sur Windows[6].

Références[modifier | modifier le wikicode]


Dockerfile

Une fois le processus Docker lancé, on peut commencer à lui demander de construire des conteneurs à partir d'images.

Rôle[modifier | modifier le wikicode]

Il existe deux sortes de conteneur :

  • Celui issu d'une image téléchargée et utilisée telle qu'elle.
  • Celui construit avec des instructions personnalisées.

Par convention, les instructions pour construire un conteneur sont écrites dans un fichier appelé "Dockerfile". Il est recommandé de les placer dans un dépôt Git pour les versionner.

Commandes Dockerfile[modifier | modifier le wikicode]

Les commentaires sont précédés du croisillon (#).

ADD[modifier | modifier le wikicode]

Permet de copier des fichiers ou dossiers de la machine hôte vers le conteneur[1].

Logo Les Dockerfile n’ont jamais accès aux volumes de l'hôte, sauf dans l’ENTRYPOINT.


ARG[modifier | modifier le wikicode]

Crée une variable qui sera accessible dans la première image (FROM). Ex :

ARG NODE_VERSION=10
...
RUN curl -sL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash

Logo Éviter d'utiliser ce système pour bénéficier du build cache : ainsi Docker ne retéléchargera pas toutes les dépendances du Dockerfile lors du changement d'une variable située en début de Dockerfile, et n'affectant qu'une seule d'entre elles.


COPY[modifier | modifier le wikicode]

Copie des fichiers ou dossiers au sein du conteneur[2].

ENTRYPOINT[modifier | modifier le wikicode]

Nom d'un fichier exécutable (par exemple en shell) qui s'exécutera après le lancement du conteneur[3].

ENV[modifier | modifier le wikicode]

Crée une variable d'environnement accessible à toutes les images du Dockerfile[4].

EXPOSE[modifier | modifier le wikicode]

Ouvre le port logiciel mentionné du conteneur[5].

FROM[modifier | modifier le wikicode]

Part d'une image Docker pour en créer une autre qui la complète[6].

Cela permet par exemple le multistage build : se servir d'une première image comme builder volumineux (avec des sources, des dépendances nécessaires à des installations), duquel on copie seulement les fichiers à utiliser dans une autre image plus légère, qui sera montée en conteneur[7].

LABEL[modifier | modifier le wikicode]

Ajoute une description à une image[8].

RUN[modifier | modifier le wikicode]

Lance une commande. Ex :

RUN ls

STOPSIGNAL[modifier | modifier le wikicode]

Signal d'arrêt à envoyer au conteneur, au format nombre ou nom. Par exemple SIGKILL pour le tuer.

USER[modifier | modifier le wikicode]

Se connecte à l'utilisateur et mot de passe en paramètre pour lancer les instructions RUN, CMD ou ENTRYPOINT[9].

VOLUME[modifier | modifier le wikicode]

Point de montage accessible par l'hôte et les autres conteneurs[10].

WORKDIR[modifier | modifier le wikicode]

Définit le répertoire de travail, c'est-à-dire celui à partir duquel les commandes partent (ex : pwd), y compris quand on se connecte au conteneur après son montage.

.dockerignore[modifier | modifier le wikicode]

Un fichier .dockerignore peut être placé dans un dépôt pour que son conteneur ignore le contenu qui y figure lors des commandes ADD et COPY. Exemple pour Symfony :

node_modules/*
var/*
vendor/*

Bonnes pratiques[modifier | modifier le wikicode]

Voir https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Exemple d'image construite[modifier | modifier le wikicode]

Voici un exemple de serveur Apache avec PHP7.1[11] :

FROM debian:sid

ENV MEDIAWIKI_VERSION wmf/1.30.0-wmf.4

# XXX: Consider switching to nginx.
RUN set -eux; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
		ca-certificates \
		apache2 \
		libapache2-mod-php7.1 \
		php7.1-mysql \
		php7.1-cli \
		php7.1-gd \
		php7.1-curl \
		php7.1-mbstring \
		php7.1-xml \
		imagemagick \
		netcat \
		git \
	; \
	rm -rf /var/lib/apt/lists/*; \
	rm -rf /var/cache/apt/archives/*; \
	a2enmod rewrite; \
	a2enmod proxy; \
	a2enmod proxy_http; \
	# Remove the default Debian index page.
	rm /var/www/html/index.html


# MediaWiki setup
RUN set -eux; \
	mkdir -p /usr/src; \
	git clone \
		--depth 1 \
		-b $MEDIAWIKI_VERSION \
		https://gerrit.wikimedia.org/r/p/mediawiki/core.git \
		/usr/src/mediawiki \
	; \
	cd /usr/src/mediawiki; \
	git submodule update --init skins; \
	git submodule update --init vendor; \
	cd extensions; \
	# Extensions
	# TODO: make submodules shallow clones?
	git submodule update --init --recursive VisualEditor; \
	git submodule update --init --recursive Math; \
	git submodule update --init --recursive EventBus; \
	git submodule update --init --recursive Scribunto; \
	git submodule update --init --recursive ParserFunctions; \
	git submodule update --init --recursive SyntaxHighlight_GeSHi; \
	git submodule update --init --recursive Cite; \
	git submodule update --init --recursive Echo; \
	git submodule update --init --recursive Flow; \
	git submodule update --init --recursive PageImages; \
	git submodule update --init --recursive TextExtracts; \
	git submodule update --init --recursive MobileFrontend; \
	git submodule update --init --recursive TemplateData; \
	git submodule update --init --recursive ParserFunctions; \
	git submodule update --init --recursive Citoid


COPY php.ini /usr/local/etc/php/conf.d/mediawiki.ini

COPY apache/mediawiki.conf /etc/apache2/
RUN echo "Include /etc/apache2/mediawiki.conf" >> /etc/apache2/apache2.conf

COPY docker-entrypoint.sh /entrypoint.sh

EXPOSE 80 443
ENTRYPOINT ["/entrypoint.sh"]
CMD ["apachectl", "-e", "info", "-D", "FOREGROUND"]

Références[modifier | modifier le wikicode]


Gestion des conteneurs

Les conteneurs sont stockés :

  • Sur Linux, dans /var/lib/docker/.
  • Sur MacOS, dans /Users/nom_utilisateur/Library/Containers/com.docker.docker/.
  • Sur Windows, dans C:\ProgramData\docker\ ou C:\ProgramData\DockerDesktop\.

run[modifier | modifier le wikicode]

Pour lancer un conteneur puis se connecter dedans, on utilise le mode interactif :

docker run -it redis

exec[modifier | modifier le wikicode]

Pour exécuter une commande dans un conteneur. Ex :

docker exec redis sh -c 'pwd'

Fonctionne aussi avec un fichier :

docker exec redis script.sh

Pour utiliser le conteneur, on peut rentrer dedans en utilisant le mode interactif :

docker exec -it redis bash

build[modifier | modifier le wikicode]

Pour lancer un conteneur à construire, il faut le faire depuis le dossier de son Dockerfile[1] :

docker build .

ps[modifier | modifier le wikicode]

Pour obtenir la liste des conteneurs lancés :

docker ps

Pour tous les conteneurs :

docker ps -a

image[modifier | modifier le wikicode]

Pour toutes les images :

docker image ls

Références[modifier | modifier le wikicode]


Docker-compose

La commande docker-compose est un utilitaire généralement fourni avec Docker, permettant d'orchestrer plusieurs images et conteneurs avec la même commande[1]. Pour ce faire, les paramétrages de l’ensemble des conteneurs doit être définit dans le fichier docker-compose.yml à la racine du projet.

Installation[modifier | modifier le wikicode]

Linux[modifier | modifier le wikicode]

Lancer[2] :

curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Commandes[modifier | modifier le wikicode]

version[modifier | modifier le wikicode]

Version de docker-compose[3]. Exemple en 2019 :

version: '3.7'

networks[modifier | modifier le wikicode]

Définition du réseau des VM Docker.

services[modifier | modifier le wikicode]

Liste des conteneurs à construire.

image[modifier | modifier le wikicode]

Nom de l'image à télécharger sur https://hub.docker.com/. Elle peut être suivie d'un tag pour en indiquer la version.

Exemples :

    image: 'mariadb'
    image: 'mariadb:latest'
    image: 'mariadb:10.4'

build[modifier | modifier le wikicode]

Alternativement à l'image, on peut indiquer le chemin d'un dockerfile pour construire son propre conteneur.

Si le conteneur ne partage aucun fichier avec d'autres, indiquer simplement le nom du dossier contenant le dockerfile :

        build: './php7.3-fpm'

Sinon, préciser le contexte où le conteneur devra récupérer les fichiers partagés nécessaires à son build :

        build:
            context: .
            dockerfile: './php7.3-fpm/Dockerfile'

volumes[modifier | modifier le wikicode]

Mapping des répertoires partagés entre la machine hôte et le conteneur :

        volumes:
            - '$HOME/www:/var/www'

La variable $HOME vaut "~" par défaut (dossier de l'utilisateur courant), mais peut être remplacée dans le fichier .env.

ports[modifier | modifier le wikicode]

Mapping du partage des ports. Ex :

        ports:
            - 3306:3306

environment[modifier | modifier le wikicode]

Injecte des variables d'environnement dans le conteneur.

env_file[modifier | modifier le wikicode]

Définit le nom d'un fichier contenant des variables d'environnement récupérables dans docker-compose.yml, avec la syntaxe "${ma_variable}". Exemple :

    env_file: .env
    environment:
        HOST_UID: "${UID}"

Logo Sur Windows le changement de l'UID entraine une modification des droits de tous les fichiers.


depends_on[modifier | modifier le wikicode]

Permet de spécifier qu'un conteneur doit en attendre un autre pour être lancé.

restart[modifier | modifier le wikicode]

Indique si le conteneur doit se lancer au démarrage du daemon Docker (donc de la machine hôte). Vaut "false" par défaut. Ex :

        restart: always

container_name[modifier | modifier le wikicode]

Permet de forcer un nom de conteneur.

hostname[modifier | modifier le wikicode]

Permet de forcer un nom de machine dans le conteneur. Utile si on a une application qui doit pointer dessus dans son .env (car "localhost" fonctionne quand le serveur était installé directement sur la machine hôte mais pas dans un conteneur).

network[modifier | modifier le wikicode]

Permet de forcer une adresse IP pour le conteneur.

Logo Dans docker-compose.yml, il faut toujours remplir le paramètre "default" de "networks" pour ne pas qu’il prenne une plage utilisée.


Exemples[modifier | modifier le wikicode]

Minimal[modifier | modifier le wikicode]

Exemple de docker-compose.yml contenant un seul conteneur CentOS, qui a le droit d'accéder au dossier ~/www :

version: '3.2'
services:
  centos:
    image: 'centos/systemd'
    volumes:
        - '$HOME/www:/var/www'

Complet[modifier | modifier le wikicode]

    mariadb:
        hostname: 'mariadb'
        image: 'mariadb:10.4'
        ports:
            - 3306:3306
        environment:
            MYSQL_ROOT_PASSWORD: 'wikibooks'
        # Partage pour les commandes SQL "into outfile" et "load data infile"
        volumes:
            - '$HOME/www:/var/www'
        restart: always
        networks:
            default:
                ipv4_address: 172.170.0.3

    adminer:
        hostname: 'adminer'
        image: 'adminer'
        ports:
            - 8080:8080
        restart: always
        networks:
            default:
                ipv4_address: 172.170.0.4

Gestion[modifier | modifier le wikicode]

Pour relancer le conteneur sur Linux :

sudo docker-compose stop; sudo docker-compose build; sudo docker-compose up -d

Pour relancer le conteneur sur Windows :

docker-compose stop; docker-compose build; docker-compose up -d

Ou le lancer et rentrer dedans en même temps :

sudo docker-compose run centos bash

Ou exécuter une seule commande shell dedans avant de revenir à la machine hôte :

sudo docker exec centos sh -c 'ls -alh'

Logs[modifier | modifier le wikicode]

Pour voir les logs de tous les conteneurs en live :

 docker-compose logs -f

Pour voir les logs d'un seul conteneur :

 docker-compose logs nom_du_conteneur


Supprimer les logs[modifier | modifier le wikicode]

L'emplacement des logs d'un conteneur est visible avec :

 docker inspect --format='{{.LogPath}}' nom_du_conteneur

Pour supprimer les logs de tous les conteneurs sur Linux :

 find /var/lib/docker/containers/ -type f -name "*.log" -delete

Puis redémarrer les conteneurs pour qu'ils recréent des logs.

Sur Windows, comme les logs sont dans le fichier C:\ProgramData\DockerDesktop\vm-data\DockerDesktop.vhdx, il faut d'abord se connecter à la VM Docker pour exécuter cette commande[4]. Exemple en DOS :

docker run --privileged -it -v /var/run/docker.sock:/var/run/docker.sock jongallant/ubuntu-docker-client 
docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged --rm -v /:/host alpine /bin/sh
chroot /host

Références[modifier | modifier le wikicode]


Kubernetes

Kubernetes permet une orchestration de plusieurs conteneurs en production. En effet, il offre des options de quotas et relances automatiques.

La configuration peut être réalisée par l'interface graphique ou par la commande kubectl[1].

pod[modifier | modifier le wikicode]

Un pod désigne un groupe de conteneur géré par Kubernetes[2].

replica set[modifier | modifier le wikicode]

Un replica set désigne un ensemble de pods, dont le nombre maximum peut y être défini.

secret[modifier | modifier le wikicode]

Mot de passe chiffré.

CronJob[modifier | modifier le wikicode]

Lance un conteneur dédié à une tâche planifiée (cron), à chaque fois qu'elle tourne[3].

Références[modifier | modifier le wikicode]


Erreurs connues

Accéder aux logs[modifier | modifier le wikicode]

Pour le démon :

 tail /var/log/docker.log 

Pour les conteneurs :

docker-compose logs

Ces deux commandes acceptent l'argument "-f" pour les afficher en temps réel.

Récupérer l'IP d'un conteneur[modifier | modifier le wikicode]

sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nom_du_conteneur

Réinitialiser les conteneurs à zéro[modifier | modifier le wikicode]

Logo Cette opération peut prendre du temps car Docker retélécharge tout les paquets ensuite.


Linux :

sudo docker rm -f $(sudo docker ps -a -q); sudo docker rmi -f $(sudo docker images -q); sudo docker network rm $(sudo docker network ls -q)

Windows :

docker rm -f $(docker ps -a -q); docker rmi -f $(docker images -q); docker network rm $(docker network ls -q)

La partie network peut être exécutée indépendamment, par exemple en cas de ERROR: Pool overlaps with other one on this address space.

Sous Windows[modifier | modifier le wikicode]

Le partage Windows ne fonctionne pas[modifier | modifier le wikicode]

Si ça n'a jamais fonctionné : ajouter son compte dans le groupe "docker user".

C'est peut-être lié à la plage d'IP de Docker, remettre celle par défaut.

Si ça marchait sur Windows 10 pro dans un Active Directory et que ça ne fonctionne plus en dehors de l'AD ou en VPN, c'est un bug avec Docker Desktop 2.1.0.5 qui semble résolu dans la 2.1.6.1. En effet, seul un admin de l'AD peut autoriser le partage des volumes, et le port 445 doit être ouvert.

Pour tester si ça marche :

 docker run -v c:/Users:/data alpine ls data

Un conteneur ne se lance pas[modifier | modifier le wikicode]

Un motif plus précis se trouve dans les logs :

sudo docker logs nom_du_conteneur

Cannot connect to the Docker daemon. Is the docker daemon running on this host?[modifier | modifier le wikicode]

Relancer docker en administrateur.

Cannot start service xxx: Address already in use[modifier | modifier le wikicode]

Deux conteneurs utilisent le même port. Dans Docker-compose, si l'un des deux avait été retiré, il était peut-être configuré en restart: always et il faut le remettre dans docker-compose.yml pour le stopper.

Cannot start service xxx :driver failed programming external connectivity on endpoint[modifier | modifier le wikicode]

Impossible de lancer un conteneur sur Windows :

  • Soit Docker n'a pas accès au volume, et il faut cocher la case "Shared drives" dans Docker Desktop, ou lancer la commande suivante en acceptant le partage :
docker run --rm -v c:/Users:/data alpine ls /data
  • Soit Docker n'a pas accès aux ports de ses conteneurs, et il faut fermer les processus qui les utilisent. Il peut même s'agir d'une deuxième instance de Docker.

Couldn't connect to Docker daemon at http+docker://localhost - is it running?[modifier | modifier le wikicode]

/etc/init.d/docker start

Si le démon ne se lance pas, upgrader l'OS et redémarrer. Sinon, réinstaller Docker.

Error response from daemon: Get https://xxx: no basic auth credentials[modifier | modifier le wikicode]

Sur certains dépôts privés, pour faire un docker pull il faut préalablement se loguer. Ex :

 docker login -u mon_utilisateur -p mon_mdp mon_url

standard_init_linux.go:211: exec user process caused "no such file or directory"[modifier | modifier le wikicode]

Changer les retours chariots du fichier appelé par "ENTRYPOINT" dans le Dockerfile, de CRLF (Windows) vers LF (Unix).

GFDL GFDL Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans texte de dernière page de couverture.