Comme je m’intéresse à PostgreSql (“The World’s Most Advanced Open Source Relational Database”) et Docker, j’ai décidé d’installer Docker et l’image PostgreSql afin d’en cerner les avantages et inconvénients par rapport à la virtualisation classique.
Préparation
Comme d’habitude, il convient de mettre à jour Debian (ici en version 11) avant d’installer des paquets:
1sudo apt-get update && sudo apt-get upgrade
Ensuite, il faut installer les paquets suivants (j’ai juste eu besoin de apt-transport-https, le reste est déjà installé sur ma version):
1sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
Installation de Docker
Ajout du repository
On commence par installer la clé PGP de Docker avec ces commandes:
1curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Puis on ajoute le repository Docker:
1echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Installation des paquets Docker
On fait une nouvelle mise à jour Debian afin de prendre en compte le repository puis on installe les paquets Docker:
Stockage des images et données
Avant d’aller plus loin, il faut savoir que les images Docker peuvent vite remplir le disque. Pour éviter que mon disque système déborde, j’ai choisi de déplacer les images dans ma partition /opt.
Pour cela, il faut d’ajouter ajouter le dossier /opt/docker_images puis il faut éditer le fichier /etc/docker/daemon.json et ajouter les lignes suivantes:
Contrôle de l’installation
Une fois l’installation terminée, on peut vérifier que Docker est prêt grâce aux commandes suivantes (réponses en bleu):
1systemctl status docker containerd
2● docker.service - Docker Application Container Engine
3 Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
4 Active: active (running) since Sat 2021-12-25 16:51:16 CET; 3min 48s ago
5TriggeredBy: ● docker.socket
6 Docs: https://docs.docker.com
7 Main PID: 28277 (dockerd)
8 Tasks: 13
9 Memory: 36.0M
10 CPU: 275ms
11 CGroup: /system.slice/docker.service
12 └─28277 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
13
14Dec 25 16:51:15 station.gtg dockerd[28277]: time="2021-12-25T16:51:15.913595169+01:00" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc
15Dec 25 16:51:15 station.gtg dockerd[28277]: time="2021-12-25T16:51:15.913612836+01:00" level=info msg="ccResolverWrapper: sending update to cc: {[{unix:///run/containerd/containerd.sock <nil> 0 <nil>}] <ni>
16Dec 25 16:51:15 station.gtg dockerd[28277]: time="2021-12-25T16:51:15.913624402+01:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc
17Dec 25 16:51:16 station.gtg dockerd[28277]: time="2021-12-25T16:51:16.016000291+01:00" level=info msg="Loading containers: start."
18Dec 25 16:51:16 station.gtg dockerd[28277]: time="2021-12-25T16:51:16.207380620+01:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used >
19Dec 25 16:51:16 station.gtg dockerd[28277]: time="2021-12-25T16:51:16.279475675+01:00" level=info msg="Loading containers: done."
20Dec 25 16:51:16 station.gtg dockerd[28277]: time="2021-12-25T16:51:16.301485806+01:00" level=info msg="Docker daemon" commit=459d0df graphdriver(s)=overlay2 version=20.10.12
21Dec 25 16:51:16 station.gtg dockerd[28277]: time="2021-12-25T16:51:16.301591296+01:00" level=info msg="Daemon has completed initialization"
22Dec 25 16:51:16 station.gtg systemd[1]: Started Docker Application Container Engine.
23Dec 25 16:51:16 station.gtg dockerd[28277]: time="2021-12-25T16:51:16.351774256+01:00" level=info msg="API listen on /run/docker.sock"
1sudo systemctl status containerd
2● containerd.service - containerd container runtime
3 Loaded: loaded (/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
4 Active: active (running) since Sat 2021-12-25 16:51:14 CET; 6min ago
5 Docs: https://containerd.io
6 Main PID: 28192 (containerd)
7 Tasks: 13
8 Memory: 21.8M
9 CPU: 252ms
10 CGroup: /system.slice/containerd.service
11 └─28192 /usr/bin/containerd
12
13Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.783865144+01:00" level=info msg="loading plugin \"io.containerd.grpc.v1.namespaces\"..." type=io.containerd.grpc.v1
14Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.783876315+01:00" level=info msg="loading plugin \"io.containerd.internal.v1.opt\"..." type=io.containerd.internal.v1
15Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784109298+01:00" level=info msg="loading plugin \"io.containerd.grpc.v1.snapshots\"..." type=io.containerd.grpc.v1
16Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784128313+01:00" level=info msg="loading plugin \"io.containerd.grpc.v1.tasks\"..." type=io.containerd.grpc.v1
17Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784142614+01:00" level=info msg="loading plugin \"io.containerd.grpc.v1.version\"..." type=io.containerd.grpc.v1
18Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784155687+01:00" level=info msg="loading plugin \"io.containerd.grpc.v1.introspection\"..." type=io.containerd.grpc.v1
19Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784347206+01:00" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
20Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784384609+01:00" level=info msg=serving... address=/run/containerd/containerd.sock
21Dec 25 16:51:14 station.gtg containerd[28192]: time="2021-12-25T16:51:14.784422458+01:00" level=info msg="containerd successfully booted in 0.047712s"
22Dec 25 16:51:14 station.gtg systemd[1]: Started containerd container runtime.
Ajout des droits utilisateurs
Par défaut, seul le root peut lancer Docker. Pour une question de facilité (démarrage à la demande) et de sécurité (on travaille le moins possible avec le compte root), il vaut mieux autoriser son compte (ou un autre) à lancer Docker. Cela se fait simplement avec la commande:
1sudo usermod -aG docker <login>
Ensuite, en voulant tester Docker avec la commande docker run hello-world
, j’ai reçu le message suivant:
1got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create?name=redis: dial unix /var/run/docker.sock: connect: permission denied
Pour corriger cela, il faut autoriser son compte (ou le même qu’à l’étape précédente) à écrire le fichier de lock avec la commande:
1sudo setfacl --modify user:<login>:rw /var/run/docker.sock
A ce stade, Docker est prêt!
Création de l’image PostgreSql
Récupération de l’image
Il existe une image PostgreSql officielle pour Docker et il faut lancer la préparation avec la commande docker pull postgres
.La réponse est la suivante:
1Using default tag: latest
2latest: Pulling from library/postgres
3a2abf6c4d29d: Pull complete
4e1769f49f910: Pull complete
533a59cfee47c: Pull complete
6461b2090c345: Pull complete
78ed8ab6290ac: Pull complete
8495e42c822a0: Pull complete
918e858c71c58: Pull complete
10594792c80d5f: Pull complete
11794976979956: Pull complete
12eb5e1a73c3ca: Pull complete
136d6360292cba: Pull complete
14131e916e1a28: Pull complete
15757a73507e2e: Pull complete
16Digest: sha256:f329d076a8806c0ce014ce5e554ca70f4ae9407a16bb03baa7fef287ee6371f1
17Status: Downloaded newer image for postgres:latest
18docker.io/library/postgres:latest
Création d’un volume de stockage
Par défaut, Docker ne persiste pas le contenu des images et c’est un peu gênant pour une base de données de voir son contenu réinitialisé à chaque démarrage. Pour activer le stockage, il faut d’abord créer un volume dédié avec la commande suivante:
1docker volume create pgdata
On peut vérifier que le volume est créé et quel dossier contient les fichiers qui vont être sauvés grâce à la commande:
1docker volume inspect pgdata
On obtient une réponse au format JSON:
En rouge, il s’agit du dossier qu’on a définit dans le fichier /etc/docker/daemon.json. En bleu, il s’agit du nom du volume.
Démarrage de l’image
Pour démarrer notre image PostgreSql, il suffit simplement d’exécuter la commande:
1docker run -d --name=pgsql -p 5432:5432 --mount source=pgdata,target=/var/lib/postgresql/data -e POSTGRES_PASSWORD=<mot de passe> postgres
On trouve beaucoup (tous en fait) de tutoriels qui indiquent d’utiliser le paramètre “-v” pour désigner le volume à prendre en compte. Cela fonctionne uniquement si le container est en mode interactif. Dans mon cas, le container est lancé en daemon (paramètre “-d”) et il faut alors utiliser le paramètre “--mount” pour lier le volume au container.
Connexion au serveur PostgreSql
J’ai ajouté une connexion dans dBeaver (un des meilleurs clients SQL Open source) comme ceci:
PostgreSql: connexion avec dBeaver
Pour vérifier que Docker ne perd pas les modifications, je vais ajouter une table à la base avec cette requête:
Contrôler la persistance du volume
Pour vérifier que le volume a bien enregistré les fichiers de PostgreSql, on va arrêter le container puis le relancer. Normalement on doit retrouver la table de test créée à l’étape précédente. On commence par trouver l’identifiant du container:
Puis on arrête le container avec la commande suivante:
1docker container stop a81ad52651f8 && docker container rm a81ad52651f8
Et maintenant on relance notre image avec la même commande qu’au lancement initial:
1docker run -d --name=pgsql -p 5432:5432 --mount source=pgdata,target=/var/lib/postgresql/data -e POSTGRES_PASSWORD=<mot de passe> postgres
Puis on se connecte au serveur PostgreSql avec dBeaver et magie! La table de test est présente.
Docker: la table est toujours présente
Conclusion
L’installation de Docker ne pose aucune difficulté, l’ajout d’image est très simple. La gestion des images et containers est plutôt aisée. Le point fort de ce type de virtualisation est de ne pas avoir à installer un OS à chaque fois.