15%

Économisez 15% sur tous les services d'hébergement

Testez vos compétences et obtenez Réduction sur tout plan d'hébergement

Utilisez le code :

Skills
Commencer
08.10.2024

Docker sur Ubuntu : Guide complet d’installation et d’utilisation

Docker est une plateforme de conteneurisation open-source qui empaquète les applications et leurs dépendances dans des unités isolées et portables appelées conteneurs. Contrairement aux machines virtuelles, les conteneurs partagent le noyau OS de l’hôte, ce qui les rend considérablement plus légers, plus rapides au démarrage et plus efficaces en termes de ressources — une distinction essentielle pour quiconque exécute des charges de travail dans un environnement VPS Hosting où les ressources de calcul affectent directement les coûts et les performances.

Ce guide couvre l’intégralité du processus d’installation de Docker sur Ubuntu 20.04, 22.04 et 24.04 LTS, y compris le durcissement post-installation, les flux de travail Docker Compose et les modèles de commandes pertinents pour la production que la plupart des tutoriels omettent.

Prérequis et configuration système requise

Avant d’exécuter la moindre commande, vérifiez les points suivants :

  • Version Ubuntu : 20.04 LTS (Focal), 22.04 LTS (Jammy) ou 24.04 LTS (Noble). La commande `lsb_release -cs` utilisée lors de la configuration du dépôt détectera automatiquement votre nom de code.
  • Architecture : `amd64`, `arm64` et `armhf` sont tous pris en charge par le dépôt officiel de Docker.
  • Version du noyau : Docker nécessite le noyau Linux 3.10 ou supérieur. Exécutez `uname -r` pour confirmer.
  • Privilèges utilisateur : `sudo` ou un accès root est obligatoire pour l’installation et la gestion du démon.
  • Espace disque : Au minimum 2 GB libres sur la partition hébergeant `/var/lib/docker`, qui est l’endroit où Docker stocke les images, les conteneurs, les volumes et le cache de construction. Sur les systèmes de production, montez ce répertoire sur une partition ou un volume dédié.

Étape critique avant l’installation : Si vous avez précédemment installé Docker depuis le dépôt `apt` par défaut d’Ubuntu (le paquet `docker.io`), supprimez-le d’abord pour éviter les conflits avec les paquets officiels Docker CE :

“`bash

sudo apt remove docker docker-engine docker.io containerd runc

“`

Étape 1 : Mettre à jour les paquets système

Mettez à jour l’index des paquets et les paquets installés vers leurs dernières versions avant d’ajouter un nouveau dépôt :

“`bash

sudo apt update

sudo apt upgrade -y

“`

Cela garantit que le résolveur de dépendances de `apt` fonctionne avec les métadonnées de paquets actuelles et que les bibliothèques de votre système de base ne sont pas obsolètes — une source courante d’erreurs d’exécution subtiles avec les applications conteneurisées.

Étape 2 : Installer Docker Engine depuis le dépôt officiel

Les dépôts `apt` par défaut d’Ubuntu fournissent un paquet appelé `docker.io`, maintenu par Canonical et généralement en retard de plusieurs versions par rapport à la version officielle de Docker. Pour une utilisation en production, installez toujours depuis le dépôt propre à Docker.

2.1 Installer les dépendances de transport et de vérification

“`bash

sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release -y

“`

Pourquoi `gnupg` ? À partir d’Ubuntu 22.04, `gpg` n’est pas toujours présent par défaut. L’inclure explicitement empêche l’importation de la clé GPG d’échouer silencieusement.

2.2 Ajouter la clé GPG officielle de Docker

“`bash

sudo install -m 0755 -d /usr/share/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

sudo chmod a+r /usr/share/keyrings/docker-archive-keyring.gpg

“`

L’étape `chmod a+r` est fréquemment omise dans les tutoriels, mais elle est nécessaire sur les systèmes où `apt` s’exécute dans un contexte utilisateur restreint — sans elle, le gestionnaire de paquets ne peut pas lire le trousseau de clés et générera une erreur `NO_PUBKEY` lors de `apt update`.

2.3 Ajouter le dépôt stable de Docker

“`bash

echo

"deb [arch=$(dpkg –print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg]

https://download.docker.com/linux/ubuntu

$(lsb_release -cs) stable" |

sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

“`

La substitution `arch=$(dpkg –print-architecture)` est essentielle sur les serveurs basés sur ARM. Coder en dur `amd64` ici est une erreur courante qui provoque des échecs silencieux de résolution de paquets sur les instances ARM.

2.4 Installer Docker Engine, CLI et les plugins

“`bash

sudo apt update

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

“`

Détail des paquets :

PaquetRôle
`docker-ce`Démon Docker Engine (`dockerd`)
`docker-ce-cli`CLI client (commande `docker`)
`containerd.io`Runtime de conteneur de bas niveau (conforme OCI)
`docker-buildx-plugin`Capacités de construction étendues (multi-plateforme, BuildKit)
`docker-compose-plugin`Compose V2 intégré comme plugin CLI Docker

Remarque sur `containerd.io` : Ce n’est pas la même chose que le paquet `containerd` dans le dépôt par défaut d’Ubuntu. Le `containerd.io` de Docker est une version spécifique et testée du runtime containerd. Mélanger les deux est une source connue d’échecs au démarrage du démon.

Étape 3 : Vérifier l’installation

Confirmez que le démon est actif et configuré pour démarrer au démarrage du système :

“`bash

sudo systemctl status docker

sudo systemctl enable docker

“`

Vérifiez la version installée :

“`bash

sudo docker –version

sudo docker info

“`

`docker info` est plus informatif que `–version` seul — il révèle le pilote de stockage utilisé (généralement `overlay2`), le pilote cgroup (`systemd` vs `cgroupfs`), ainsi que le nombre de CPU et la mémoire auxquels Docker peut accéder.

Exécutez le test de vérification canonique :

“`bash

sudo docker run hello-world

“`

Une exécution réussie affiche un message « Hello from Docker ! » et confirme que le démon Docker, le téléchargement d’image depuis Docker Hub et l’exécution du conteneur fonctionnent tous correctement.

Étape 4 : Configurer Docker pour un accès sans root

Par défaut, le socket Docker (`/var/run/docker.sock`) appartient à `root` et au groupe `docker`. Tout utilisateur n’appartenant pas au groupe `docker` doit utiliser `sudo` pour chaque commande Docker.

“`bash

sudo usermod -aG docker $USER

“`

Appliquez l’appartenance au groupe sans vous déconnecter :

“`bash

newgrp docker

“`

Vérifiez :

“`bash

docker run hello-world

“`

Avertissement de sécurité : L’appartenance au groupe `docker` est effectivement équivalente à un accès `sudo` sans mot de passe. Un utilisateur dans le groupe `docker` peut facilement monter le système de fichiers hôte dans un conteneur et contourner tous les contrôles d’accès au niveau du système de fichiers. Sur les systèmes multi-locataires ou les serveurs partagés, envisagez plutôt d’utiliser Docker rootless :

“`bash

dockerd-rootless-setuptool.sh install

“`

Le mode rootless exécute le démon Docker et les conteneurs sous un espace de noms utilisateur non privilégié, réduisant considérablement la surface d’attaque. Il s’agit de la configuration recommandée pour tout environnement où plusieurs utilisateurs partagent le même hôte.

Étape 5 : Référence des commandes Docker essentielles

Gestion des images

“`bash

Pull a specific image version from Docker Hub

docker pull nginx:1.27-alpine

List locally cached images

docker images

Remove a specific image

docker rmi nginx:1.27-alpine

Remove all dangling (untagged) images to reclaim disk space

docker image prune

Remove all unused images (not just dangling)

docker image prune -a

“`

Conseil de production : Utilisez toujours des tags versionnés (par ex., `nginx:1.27-alpine`) plutôt que `latest` dans tout flux de travail automatisé ou de production. Le tag `latest` est mutable — il peut pointer vers une image différente après un push dans le registre, compromettant la reproductibilité.

Cycle de vie des conteneurs

“`bash

Run a container interactively with a pseudo-TTY

docker run -it ubuntu:22.04 /bin/bash

Run a container in detached mode with port mapping and a name

docker run -d -p 8080:80 –name my-nginx nginx:1.27-alpine

List running containers

docker ps

List all containers (including stopped)

docker ps -a

Stop a running container gracefully (SIGTERM, then SIGKILL after timeout)

docker stop my-nginx

Start a stopped container

docker start my-nginx

Remove a stopped container

docker rm my-nginx

Force-remove a running container (sends SIGKILL immediately)

docker rm -f my-nginx

View real-time logs

docker logs -f my-nginx

Execute a command inside a running container

docker exec -it my-nginx /bin/sh

“`

Inspection des ressources et du système

“`bash

Display real-time resource usage statistics

docker stats

Inspect detailed container metadata (JSON)

docker inspect my-nginx

Display disk usage by Docker objects

docker system df

Remove all stopped containers, unused networks, dangling images, and build cache

docker system prune

“`

`docker system prune` est l’une des commandes de maintenance les plus importantes pour les serveurs à longue durée de fonctionnement. Sans nettoyage périodique, le cache de construction de Docker et les conteneurs arrêtés peuvent consommer des dizaines de gigaoctets sur un hôte de développement ou CI actif.

Étape 6 : Docker Compose — Orchestration d’applications multi-conteneurs

Docker Compose V2 (le `docker-compose-plugin` installé précédemment) est invoqué avec `docker compose` (avec un espace), et non avec l’ancienne syntaxe `docker-compose` (avec un tiret). Les deux syntaxes fonctionnent si vous avez le plugin installé, mais V2 est la norme actuelle.

6.1 Comprendre la structure du fichier Compose

Créez un répertoire de projet et un fichier `compose.yml` (le nom de fichier préféré dans Compose V2 ; `docker-compose.yml` reste pris en charge pour la compatibilité ascendante) :

“`bash

mkdir ~/my-web-app && cd ~/my-web-app

nano compose.yml

“`

Un exemple réaliste pour la production avec Nginx et un service backend :

“`yaml

services:

web:

image: nginx:1.27-alpine

ports:

  • "8080:80"

volumes:

  • ./nginx.conf:/etc/nginx/nginx.conf:ro
  • ./html:/usr/share/nginx/html:ro

depends_on:

  • app

restart: unless-stopped

app:

image: node:20-alpine

working_dir: /usr/src/app

volumes:

  • ./app:/usr/src/app

command: node server.js

environment:

  • NODE_ENV=production

restart: unless-stopped

“`

Explication des directives Compose clés :

  • `restart: unless-stopped` — Le conteneur redémarre automatiquement après un crash ou un redémarrage du système, sauf s’il a été explicitement arrêté par l’opérateur. Il s’agit de la politique correcte pour les services à longue durée de fonctionnement ; `always` redémarrera même les conteneurs intentionnellement arrêtés.
  • `depends_on` — Contrôle l’ordre de démarrage mais n’attend pas que le service soit *prêt* (par ex., une base de données acceptant des connexions). Pour le contrôle de disponibilité, utilisez `healthcheck` combiné avec `condition: service_healthy`.
  • `volumes` avec `:ro` — Monter les fichiers de configuration en lecture seule empêche un processus de conteneur compromis de modifier sa propre configuration.

6.2 Commandes du flux de travail Compose

“`bash

Start all services in detached mode

docker compose up -d

View logs for all services

docker compose logs -f

View logs for a specific service

docker compose logs -f web

List running Compose services

docker compose ps

Scale a specific service to multiple replicas

docker compose up -d –scale app=3

Stop services without removing containers

docker compose stop

Stop and remove containers, networks, and volumes

docker compose down –volumes

Rebuild images before starting (useful after code changes)

docker compose up -d –build

“`

6.3 Vérifier le service en cours d’exécution

“`bash

curl -I http://localhost:8080

“`

Une réponse `200 OK` confirme que Nginx fonctionne correctement. Pour les services s’exécutant sur une instance VPS Hosting distante, remplacez `localhost` par l’adresse IP publique de votre serveur et assurez-vous que le port concerné est ouvert dans votre pare-feu (`ufw allow 8080/tcp`).

Étape 7 : Fondamentaux du réseau Docker

Comprendre le modèle réseau de Docker est essentiel pour créer des applications multi-conteneurs qui communiquent de manière sécurisée.

Pilotes réseau par défaut :

PiloteCas d’utilisation
`bridge`Par défaut pour les conteneurs autonomes ; espace de noms réseau isolé sur l’hôte
`host`Le conteneur partage la pile réseau de l’hôte ; performances maximales, zéro isolation
`none`Aucun accès réseau ; utile pour le traitement par lots ou les charges de travail sensibles à la sécurité
`overlay`Réseau multi-hôtes pour les clusters Docker Swarm
`macvlan`Attribue une adresse MAC au conteneur ; apparaît comme un périphérique physique sur le réseau

Création et utilisation d’un réseau bridge personnalisé :

“`bash

Create an isolated network

docker network create my-app-network

Run containers attached to the custom network

docker run -d –name db –network my-app-network postgres:16-alpine

docker run -d –name api –network my-app-network my-api-image

Containers on the same custom bridge network can resolve each other by name

Inside 'api', you can connect to 'db' using the hostname 'db'

“`

Les réseaux bridge personnalisés fournissent une résolution DNS automatique entre les conteneurs par nom de conteneur. Le réseau `bridge` par défaut ne le fait pas — c’est une distinction essentielle qui provoque des échecs de connexion lorsque les développeurs supposent que les conteneurs sur le réseau par défaut peuvent se joindre mutuellement par nom.

Étape 8 : Données persistantes avec les volumes Docker

Les conteneurs sont éphémères par conception. Toute donnée écrite dans le système de fichiers d’un conteneur est perdue lorsque le conteneur est supprimé. Pour le stockage persistant, utilisez des volumes ou des montages liés.

“`bash

Create a named volume

docker volume create pgdata

Use the volume with a container

docker run -d

–name postgres-db

-e POSTGRES_PASSWORD=securepassword

-v pgdata:/var/lib/postgresql/data

postgres:16-alpine

List volumes

docker volume ls

Inspect a volume (shows mount point on host)

docker volume inspect pgdata

Remove unused volumes

docker volume prune

“`

Volumes vs. montages liés :

FonctionnalitéVolume nomméMontage lié
Géré par DockerOuiNon
Chemin hôte requisNonOui
Portable entre hôtesOui (avec pilotes de volume)Non
Idéal pourDonnées de base de données, état de l’applicationCode de développement, fichiers de configuration
Mécanisme de sauvegarde`docker run –volumes-from`Outils système de fichiers standard

Étape 9 : Maintenir Docker à jour

Le dépôt officiel de Docker gère les mises à jour via le mécanisme standard `apt` :

“`bash

sudo apt update

sudo apt upgrade -y

“`

Pour mettre à jour uniquement les paquets liés à Docker sans mettre à niveau l’ensemble du système :

“`bash

sudo apt install –only-upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

“`

Consultez les notes de version de Docker avant les mises à niveau de versions majeures, en particulier pour les modifications apportées au pilote de stockage, à la gestion des versions cgroup ou aux versions d’API obsolètes susceptibles d’affecter les fichiers `compose.yml` existants.

Docker vs. approches alternatives de conteneurisation

FonctionnalitéDocker EnginePodmanLXC/LXDcontainerd (autonome)
Architecture du démonDémon centraliséSans démonBasé sur un démonBasé sur un démon
Prise en charge rootlessOui (v20+)NatifLimitéeOui
Prise en charge Docker ComposeNatifVia `podman-compose`NonNon
Conformité OCIOuiOuiNon (format LXC)Oui
Intégration KubernetesVia le shim CRI-dockerdCRI natifNonCRI natif
Prise en charge Windows/macOSDocker DesktopLimitéeNonNon
Meilleure adéquationDéveloppement général et productionAxé sur la sécurité, rootlessConteneurs système, VMsNœuds Kubernetes

Pour les équipes exécutant des charges de travail conteneurisées à grande échelle sur du matériel bare metal, un environnement Dedicated Servers vous donne un contrôle total sur les paramètres du noyau, la planification des E/S de stockage et la configuration réseau — tous ces éléments affectant directement la densité des conteneurs et les performances.

Liste de contrôle pour le durcissement en production

Avant d’exécuter Docker dans un environnement de production, traitez les points suivants :

Configuration du démon (`/etc/docker/daemon.json`) :

“`json

{

"log-driver": "json-file",

"log-opts": {

"max-size": "10m",

"max-file": "3"

},

"storage-driver": "overlay2",

"userns-remap": "default",

"live-restore": true,

"no-new-privileges": true

}

“`

  • `log-opts` avec `max-size` et `max-file` : Sans rotation des journaux, les fichiers journaux JSON de Docker rempliront votre disque. C’est l’une des causes les plus courantes de pannes de serveur inattendues sur les hôtes conteneurisés.
  • `userns-remap: "default"` : Active le remappage des espaces de noms utilisateur, de sorte que le root du conteneur (UID 0) corresponde à un UID non privilégié sur l’hôte.
  • `live-restore: true` : Permet aux conteneurs de continuer à fonctionner si le démon Docker plante ou est redémarré lors d’une mise à niveau — essentiel pour une maintenance sans interruption de service.
  • `no-new-privileges: true` : Empêche les processus de conteneur d’obtenir des privilèges supplémentaires via des binaires `setuid` ou `setgid`.

Considérations réseau et pare-feu :

Docker manipule `iptables` directement et contourne les règles `ufw` par défaut. Un conteneur avec un port publié (`-p 8080:80`) sera accessible depuis Internet même si `ufw deny 8080` est défini. Pour appliquer les règles `ufw` sur la manipulation `iptables` de Docker, ajoutez `"iptables": false` à `daemon.json` et gérez le routage manuellement, ou utilisez le `–network host` de Docker avec des règles `ufw` explicites.

Pour les projets nécessitant une terminaison HTTPS, associez votre application conteneurisée à un proxy inverse correctement configuré (Nginx ou Traefik) et un certificat valide. Les SSL Certificates sont un prérequis pour tout service web de production s’exécutant derrière une pile conteneurisée.

Si votre charge de travail implique l’inférence d’apprentissage automatique, la diffusion de modèles ou le traitement de données accéléré par GPU dans des conteneurs, le NVIDIA Container Toolkit s’intègre directement avec Docker Engine. Le GPU Hosting fournit le matériel sous-jacent requis pour ces charges de travail.

Pour les équipes gérant plusieurs projets avec une gestion de conteneurs basée sur le web, le VPS with cPanel offre un environnement de panneau de contrôle géré qui peut compléter les déploiements basés sur Docker pour des piles d’applications plus simples.

Points techniques clés et matrice de décision

Quand utiliser Docker sur un VPS plutôt que sur un serveur dédié :

  • Utilisez un VPS pour les environnements de développement, la mise en scène et les charges de travail de production à trafic faible à moyen où la densité des conteneurs est de 10 à 50 conteneurs.
  • Utilisez un serveur dédié lorsque la densité des conteneurs dépasse 50 instances, lorsque vous avez besoin de performances d’E/S prévisibles (pas d’effet de voisin bruyant), ou lorsque le réglage des paramètres du noyau (`sysctl`) est requis pour votre charge de travail.

Liste de contrôle opérationnelle avant la mise en production :

  • Configurer la rotation des journaux dans `daemon.json` (`max-size`, `max-file`)
  • Activer `live-restore` pour survivre aux redémarrages du démon sans interruption des conteneurs
  • Utiliser des volumes nommés, et non des montages liés, pour les données de services avec état
  • Épingler les versions d’images dans tous les fichiers `compose.yml` — ne jamais utiliser `latest` en production
  • Activer `userns-remap` ou exécuter Docker rootless sur les hôtes multi-locataires
  • Auditer les règles `iptables` après l’installation de Docker pour confirmer que la politique de pare-feu n’est pas contournée
  • Définir `restart: unless-stopped` sur tous les services à longue durée de fonctionnement
  • Exécuter `docker system prune` dans une tâche cron planifiée pour éviter l’épuisement du disque
  • Utiliser des réseaux bridge personnalisés pour toutes les communications inter-conteneurs — ne jamais s’appuyer sur le bridge par défaut pour la découverte de services

FAQ

Docker sur Ubuntu utilise-t-il `systemd` ou `cgroupfs` comme pilote cgroup par défaut ?

Depuis Docker Engine 20.10, le pilote cgroup par défaut sur les systèmes basés sur `systemd` (y compris toutes les versions LTS modernes d’Ubuntu) est `systemd`. Cela s’aligne sur les exigences de Kubernetes et évite l’instabilité causée par l’exécution simultanée de deux gestionnaires cgroup. Vous pouvez vérifier avec `docker info | grep -i cgroup`.

Quelle est la différence entre `docker compose down` et `docker compose stop` ?

`docker compose stop` arrête les conteneurs en cours d’exécution mais les préserve ainsi que leurs réseaux associés. `docker compose down` arrête les conteneurs puis les supprime ainsi que les réseaux créés par Compose. Ajouter `–volumes` à `down` supprime également les volumes nommés définis dans le fichier Compose — utilisez cet indicateur avec précaution en production, car il supprime définitivement les données persistantes.

Pourquoi Docker contourne-t-il les règles de pare-feu `ufw` sur Ubuntu ?

Docker insère ses propres règles `iptables` dans les chaînes `DOCKER` et `DOCKER-USER`, qui sont évaluées avant les règles de la chaîne `INPUT` de `ufw`. Cela signifie qu’un port publié avec `-p` est accessible depuis Internet quelle que soit la politique `ufw`. La bonne solution est d’ajouter des règles directement à la chaîne `DOCKER-USER`, ou de lier les ports publiés à une interface spécifique (par ex., `-p 127.0.0.1:8080:80`) lorsque l’accès externe n’est pas requis.

Comment limiter le CPU et la mémoire qu’un conteneur Docker peut consommer ?

Utilisez des indicateurs de contrainte de ressources à l’exécution : `docker run –memory="512m" –cpus="1.5" my-image`. Dans Compose, définissez-les sous la clé `deploy.resources` (Compose V2) ou les clés de niveau supérieur `mem_limit` et `cpus`. Sans limites, un seul conteneur incontrôlé peut épuiser les ressources de l’hôte et faire tomber tous les autres conteneurs sur le même hôte.

Puis-je exécuter Docker dans un conteneur Docker (Docker-in-Docker) ?

Oui, mais cela est fortement déconseillé pour une utilisation en production. Le modèle courant pour les pipelines CI consiste à monter le socket Docker de l’hôte (`-v /var/run/docker.sock:/var/run/docker.sock`) dans le conteneur CI, ce qui donne au conteneur un contrôle total sur le démon Docker de l’hôte — un risque de sécurité important. Une alternative plus sûre consiste à utiliser l’indicateur `–allow security.insecure` de BuildKit ou des outils dédiés comme Kaniko ou Buildah, qui construisent des images OCI sans nécessiter de démon Docker.

15%

Économisez 15% sur tous les services d'hébergement

Testez vos compétences et obtenez Réduction sur tout plan d'hébergement

Utilisez le code :

Skills
Commencer