Juste un tutoriel Docker

L’entrepôt Docker Hub stocke des images et les distribue publiquement. Des images inactives sont soit importées soit fabriquées localement. Un conteneur (une image activée) fait tourner localement une application.

Solomon Hykes, travaille pour DotCLoud à New-York lorsqu’il publie Docker en open-source le 13 mars 2013. Cela lui porte chance et le succès est rapidement au rendez-vous. Les contributeurs aux projets et sous-projets se comptent maintenant en milliers. Docker est une solution de virtualisation qui tourne de manière standard sous Linux. Docker se base sur une librairie propre dédiée à la conteneurisation nommée libcontainer écrite nativement en Google Go et portée aussi en d’autres langages. L’installation de Docker est possible sur l’ensemble des OS récents.

Un conteneur correspond à un système de virtualisation conçu pour faire tourner une application web et ses dépendances dans un environnement Linux indépendamment du système d’exploitation de votre PC. Docker comprend un client et un démon. Le client gère les commandes Docker et transmet les informations au démon qui fait le travail et retourne le résultat au client, c’est à dire au navigateur. Docker rend possible la manipulation de deux catégories principales d’objets : des images inactives susceptibles d’être échangées ou construites localement, et des conteneurs actifs ou ayant déjà tourné qui sont des instances des images.

Les images les plus téléchargées depuis Docker Hub en plus d’hello-world ou de docker/getting-started font tourner des systèmes d’exploitation comme Debian, Linux Alpine ou Ubuntu. Un serveur comme Apache ou Nginx, un langage informatique tel que PHP, Python ou javascript/Node.js, une base de donnée comme MySQL, MariaDb, Redis ou Neo4j, un moteur de recherche comme Sphinx, ElasticSearch ou SolR, un gestionnaire de contenu tel que Drupal, WordPress ou Omeka constituent des exemples d’images susceptibles d’être téléchargées et conteneurisées avec Docker. Un conteneur se distingue d’une machine virtuelle par sa légèreté, par le fait que les ressources à mettre en œuvre sont considérablement réduites, par le fait que seuls les téléchargements nécessaires sont réalisés.

Une image est un fichier statique non modifiable composé d’un ensemble de couches qui permettent de configurer un conteneur pleinement opérationnel. Un conteneur est créé lorsqu’une image est lancée. Docker Hub https://hub.docker.com est un lieu d’échange d’images officielles proposées par les éditeurs de logiciels et personnalisées. Tout le monde peut télécharger (pull) ou bien au contraire mettre à disposition (push) des images via cette plaque tournante en accès libre inspirée de GitHub.

Des logiciels complémentaires viennent étendre les fonctionnalités de base de Docker. On peut citer parmi ceux-ci Docker Compose que nous allons manipuler dans ce tutoriel. D’autres logiciels automatisent le déploiement comme Kubernetes, Mesos ou Docker swarm. Le mouvement d’ingénierie informatique Devops s’appuie en grande partie sur l’usage de Docker pour apporter de l’agilité dans le développement et la maintenance des applications. Le dialogue entre développeurs et responsables des infrastructures informatiques s’en trouve facilité. Docker Compose s’avère rapidement indispensable pour orchestrer le fonctionnement de plusieurs conteneurs.

Nous verrons dans ce tutoriel une méthode simple pour installer Docker et Docker Compose sous Linux ou WSL. Nous nous servirons de Docker Hub pour installer et paramétrer un serveur Nginx tournant dans un environnement Linux alpine. Docker Desktop for Windows, Docker Desktop for Mac ou Docker for Linux doivent tout d’abord être installés et lancés. L’installation sous Linux est montrée. Les mêmes choses quasiment peuvent être faites sous linux avec un terminal Ubuntu par exemple, ou bien sous windows à l’aide de PowerShell. Vous pouvez alors passer au point 2 de ce tutoriel.

  1. Installation de Docker sous Linux
  2. Commandes Docker
  3. Le conteneur “hello-world”
  4. Le conteneur Linux alpine
  5. Construire son image avec Dockerfile
  6. Orchestrez vos applications avec Docker Compose
  7. Un serveur nginx avec Docker
  8. Conclusion

1. Installation de Docker sous Linux

Sous Linux, passage en mode administrateur

sudo su

Installation de Docker depuis docker.io, le paquet Docker fourni par la communauté Ubuntu

apt-get install -y docker.io

Démarrage du démon Docker

/etc/init.d/docker start

Liste des commandes Docker

docker

Aide en ligne de commande sur les instructions avec –help

docker run --help

Une documentation officielle se trouve sur docs.docker. « Docker Desktop for Windows » et « Docker Desktop for Mac ».

2. Commandes Docker

Plusieurs actions sur différentes sortes d’objets sont maintenant possibles :

  1. Actions Docker générales : events, info, inspect, network, node, service, swarm, version
  2. Échanges avec Docker Hub ou avec un entrepôt local : login, logout, pull, push, search
  3. Actions sur les images : build, commit, history, images, import, load, rmi, save, tag
  4. Actions sur les conteneurs : attach, cp, create, diff, exec, export, kill, logs, pause, port, ps, rename, restart, rm, run, start, stats, stop, top, unpause, update, volume, wait

3. Le conteneur “hello-world”

Démarrons un premier conteneur :

docker run hello-world

Plusieurs opérations se déroulent successivement avec la simple instruction “run”. Si l’image du nom de “hello-world” est absente localement, celle-ci est recherchée sur Docker hub et téléchargée. Elle devient ensuite référencée comme disponible dans l’entrepôt local et ne sera téléchargée ainsi qu’une seule fois. Puis l’image est activée et le conteneur “hello-world” devient lancé avec l’instruction « run ». Les fonctionnalités de ce conteneur sont simplement d’afficher un message d’information sur les actions du client et du démon Docker :

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

78445dd45222: Pull complete 
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

On peut ensuite lister les conteneurs actifs avec la commande ps et l’option -a. Le conteneur est rendu inactif (enlevé) en spécifiant rm et le numéro obtenu précédemment. L’image est ensuite supprimée avec rmi :

docker ps -a
docker rm 5bfb5f679559
docker images
docker rmi bf756fb1ae65

Un deuxième conteneur nommé docker/getting-started plus intéressant peut être lancé. Il permet d’afficher la documentation MkDocs de Docker sur le port 8080 : http://localhost:8080. Cela se passe toujours avec l’instruction docker run. L’option -d indique le mode détaché : la main est rendue à l’utilisateur après lancement du conteneur. L’option -p 8080:80 indique l’appariement (mapping) entre le port 8080 du navigateur et le port 80 standard du conteneur :

docker run -d -p 8080:80 docker/getting-started
docker ps -a
docker stop <CONTAINER_ID>

4. Le conteneur Linux alpine

Installons un système d’exploitation autre qu’Ubuntu. Alpine est une distribution Linux légère dont plusieurs images sont présentes sur DockerHub. Créée en 2010, cette distribution se déclare indépendante, non commerciale, et généraliste, adaptée pour la sécurité, la simplicité et l’efficacité. Alpine Linux conduit à des images bien plus petites en général. Faisons tourner un conteneur alpine et entrons à l’intérieur de celui-ci pour voir ce qui s’y passe.

Alpine Linux, Linux alpine : https://alpinelinux.org/

4.1 Téléchargement d’alpine

Chercher les images Alpine sur Docker Hub

docker search alpine

Téléchargement de l’image officielle

docker pull alpine

Historique de l’image alpine

docker history alpine

Affiche de toutes les images présentes localement

docker images

4.2 Lancement du conteneur alpine

L’instruction “run” vérifie que l’image “alpine” est présente dans le répertoire Docker local. En cas d’absence, le téléchargement est fait. Le conteneur correspondant à l’image est ensuite lancé. La commande “ls -l” passée en argument affiche la liste des répertoires et fichiers dans l’environnement alpine.

docker run alpine ls -l

Une autre commande peut être testée.

docker run alpine echo "Salut la compagnie, ohé, ohé, ohé"

Celle-ci affiche le message : le client après avoir lancé un conteneur “alpine” fait tourner la commande “echo”. Il transmet les instructions au démon qui fournit le résultat. Entrons maintenant à l’intérieur du conteneur alpine pour en tester quelques fonctionnalités.

docker run -it alpine /bin/sh

Nous sommes à l’intérieur du conteneur alpine et pouvons entrer des commandes telles que “ls -s” ou “uname -a”. La commande exec permet par exemple d’entrer dans un conteneur actif pour naviguer à l’intérieur :

docker exec -it <container_id> bash

Pour sortir du conteneur : “exit”.

4.3 Quelques commandes Docker

D’autres commandes peuvent être explorées. Elles sont assorties d’options parmi lesquels -i (interactif), -t (allocation d’un pseudo TTY), -d (conteneur en arrière plan, détaché), -a (all) sont souvent utilisées. Liste des conteneurs actifs, liste des conteneurs actifs et inactifs :

docker ps
docker ps -a

Arrêt d’un conteneur actif en spécifiant l’id ou le nom de celui-ci

docker stop 16566238781a

Suppression d’un conteneur

docker rm 16566238781a

Liste des images

docker images

Liste des métadonnées associées à une image

docker inspect hello-world

Suppression d’une image

docker rmi hello-world

Nettoyage de tous les conteneurs inactifs et de toutes les images inutilisées

docker rm $(docker ps -a -q)
docker rmi $(docker images -q)

5. Construire son image avec Dockerfile

Des images personnalisées peuvent être construites à l’aide d’instructions particulières écrites dans un fichier nommé Dockerfile. La première des commandes est FROM qui précise l’image de départ. D’autres  sont ADD, CMD, COPY, ENTRYPOINT, ENV, EXPOSE, MAINTAINER, RUN, USER, VOLUME, WORKDIR… Des volumes peuvent ainsi être montés ou copiés (ADD, COPY), des commandes Linux tournent (CMD, RUN), etc. Dans cet exemple basique, une image modifiée d’Alpine est créée, nommée mon-alpine :

mkdir images
cd images
nano Dockerfile

Contenu de Dockerfile : on précise l’image et une commande est lancée qui liste les répertoires courants du conteneur.

FROM alpine
CMD ["ls","-al"]

Construction de l’image “mon-alpine” marquée du tag latest.

docker build -t mon-alpine:latest .

Liste des images présentes dans l’entrepôt local

docker images

Lancement du conteneur “mon-alpine”.

docker run -it mon-alpine

6. Orchestrez vos applications avec Docker Compose

Les applications tournent généralement à l’aide de plusieurs conteneurs qui partagent des volumes, sont liés, démarrés ou arrêtés simultanément. Outil officiel de Docker, Docker Compose (docker-compose) facilite grandement ce genre d’opérations. Docker Compose ne fait cependant pas partie de docker.io. Son installation s’avère plus aisée en passant par les bibliothèques python accessibles via pip. Les instructions de Docker Compose sont listées dans le fichier docker-compose.yml au format Yaml, localisé à la racine du répertoire de l’application.

6.1 Installation de docker-compose

apt-get -y install python-pip
pip install docker-compose

6.2 Quelques instructions et aides

Vous pouvez tester quelques unes des commandes et arguments suivants :

docker-compose (commande de base)
docker-compose -v (information de version)
docker-compose -h (liste des commandes)
docker-compose up --help (aide sur la commande up)
docker-compose ps (liste des conteneurs)
docker-compose stop (arrêt des conteneurs, sans les enlever)
docker-compose rm  (enlève les conteneurs arrêtés)

6.3 Édition d’un fichier docker-compose.yml

L’image hello-world créée précédemment est ici lancée avec Docker Compose.

mkdir hello-world
cd hello-world
nano docker-compose.yml

Le fichier docker-compose.yml est créé dans hello-world. Avec YAML, format respecté par ce fichier, l’indentation est significative, le # indique un commentaire. La version 2 de docker-compose est spécifiée. Lancement d’un conteneur nommé mon-test à partir de l’image hello-world. Plutôt basique comme symphonie !

# hello-world avec docker-compose
version: "2"
services:
  mon-test:
    image: hello-world

6.4 Lancement de Docker Compose

docker-compose up

Et voilà, affichage :

Starting helloworld_mon-test_1
Attaching to helloworld_mon-test_1
mon-test_1  | 
mon-test_1  | Hello from Docker!
mon-test_1  | This message shows that your installation appears to be working correctly.
mon-test_1  | 
mon-test_1  | To generate this message, Docker took the following steps:
mon-test_1  |  1. The Docker client contacted the Docker daemon.
mon-test_1  |  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
mon-test_1  |  3. The Docker daemon created a new container from that image which runs the
mon-test_1  |     executable that produces the output you are currently reading.
mon-test_1  |  4. The Docker daemon streamed that output to the Docker client, which sent it
mon-test_1  |     to your terminal.
mon-test_1  | 
mon-test_1  | To try something more ambitious, you can run an Ubuntu container with:
mon-test_1  |  $ docker run -it ubuntu bash
mon-test_1  | 
mon-test_1  | Share images, automate workflows, and more with a free Docker ID:
mon-test_1  |  https://cloud.docker.com/
mon-test_1  | 
mon-test_1  | For more examples and ideas, visit:
mon-test_1  |  https://docs.docker.com/engine/userguide/
mon-test_1  | 
helloworld_mon-test_1 exited with code 0

Le conteneur “hello-world” a tourné et les commentaires s’affichent. Arrêt avec l’instruction docker-compose stop.

L’aide officielle (anglais) :

7. Un serveur nginx avec Docker

Il existe plusieurs manières de se servir de Docker. Nous allons maintenant faire tourner un serveur Nginx en employant successivement trois méthodes différentes. Nginx (prononcer « engine-x ») est un serveur Web open source développé originellement par Igor Sysoev pour les besoins d’un site moscovite à fort trafic. Ses objectifs en 2002 étaient de mettre au point un serveur haute performance dont la consommation en mémoire est faible comparativement à Apache. Écrit en C, le logiciel se caractérise par son architecture modulaire. Nginx devient très employé à partir de 2006, date de la traduction en anglais de la doc. Les fichiers servis se trouvent ici sous /app. Le fichier de configuration du serveur est localisé sous /nginx. Le fichier Dockerfile effectue les appariements et les copies des fichiers de l’arborescence dans le conteneur. Le fichier docker-compose.yml finalement sert au démarrage simplifié montré en dernier. L’application sera visible sur le port 8080. On a l’arborescence :

├── app
│   └── index.html
├── nginx
│   └── default.conf
├── Dockerfile
└── docker-compose.yml

7.1 Page d’accueil de l’application

mkdir app
echo 'hello world!' > app/index.html

7.2 Fichier de configuration du serveur

mkdir nginx
nano ./nginx/default.conf

Contenu de default.conf

server {
    index index.html;
    server_name test;
    root /app;
}

7.3 Fichier Dockerfile

On demande la copie des répertoire /app et /nginx de configuration dans le conteneur.

nano Dockerfile
FROM nginx:alpine
COPY /app /usr/share/nginx/html
COPY /nginx/default.conf /etc/nginx/conf.d/site.conf

7.4 Fichier docker-compose.yml

nano docker-compose.yml

Les mapping les fichiers sous Linux et les fichiers du conteneur sont décrits avec image, port et volume :

# Nginx sur le port 8080
version: "2"
services:
  webserver:
    image: nginx:alpine
    build: .
    ports:
      - "8080:80"
    volumes:
      - ./app:/usr/share/nginx/html
      - ./nginx/default.conf:/etc/nginx/conf.d/site.conf

7.5 Démarrage du conteneur

Trois méthodes de démarrage sont successivement testées pour lancer le conteneur.

7.5.1 En une seule ligne de commande

Le conteneur est démarré sur le port 8080 en mode détaché -d. L’option -p indique le port et le port 8080 est apparié avec le port 80 du conteneur docker. L’option -v précise le montage des volumes. Attention aux chemins ! Vous devez indiquer le chemin absolu ce que se fait ici avec la commmande $(pwd). Tout est spécifié en une ligne de commande, moyennement lisible :

docker run --name mon-nginx -p 8080:80 -v $(pwd)/app:/usr/share/nginx/html -v $(pwd)/nginx/default.conf:/etc/nginx/conf.d/site.conf -d nginx:stable

Le navigateur affiche « Hello World ».
http://localhost:8080/

Arrêt et suppression de ce premier conteneur « mon-nginx » :

docker stop mon-nginx
docker rm mon-nginx

Arrêt et suppression de tous les conteneurs

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

7.5.2 Avec Dockerfile

Construction d’une image nommée image-nginx dont les caractéristiques sont fournies par Dockerfile

docker build . -t image-nginx

Lancé à partir de l’image image-nginx, le conteneur conteneur-nginx tourne en mode détaché sur le port 8080 :

docker run --name conteneur-nginx -d -p 8080:80 image-nginx

Le conteneur tourne-t-il et la page est elle bien servie ?
http://localhost:8080/index.html

Arrêt et suppression du conteneur conteneur-nginx, puis suppression de l’image image-nginx :

docker stop conteneur-nginx
docker rm conteneur-nginx
docker rmi image-nginx
docker images

7.5.3 Avec Docker compose

Le fichier docker-compose.yml fabriqué en 7.4 est pris en compte.

docker-compose up -d

Vérification du fonctionnement, puis arrêt de docker-compose et suppression du conteneur.

docker-compose stop
docker-compose ps
docker-compose rm

Quelques liens : 

Et voici maintenant quelques ressources pour faire tourner localement WordPress, Omeka Classic et Omeka S en quelques étapes :

8. Conclusion

Vous disposez maintenant d’un Docker et d’un Docker Compose fonctionnels. Vous savez construire vos images et lancer de différentes manières un conteneur Linux alpine et un serveur nginx, applications optimisées pour leur faible consommation en ressources. Les choses sérieuses peuvent commencer ! Enjoy Docker.

2 commentaires

  1. Merci Pierre pour cette présentation très complète.
    je suis en train d’explorer Cloudron (https://cloudron.io/), une plate forme de gestion d’applications packagées et associées à des usagers via ldap.
    Ce serait vraiment très bien d’y intégrer les Omeka

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s