Installer Docker sur WSL Debian
Docker Root vs Rootless
- Le démon s'exécute avec les privilèges maximums
- Un conteneur compromis peut accéder à l'hôte entier
- Modification possible des fichiers système
- Escalade de privilèges jusqu'à root possible
- Démon et conteneurs sans privilèges root
- En cas de faille, droits limités à l'utilisateur
- Isolation stricte entre utilisateurs
- Recommandé pour tout environnement
Prérequis
- Windows 10/11 avec WSL2 activé
- Une distribution Debian installée depuis le Microsoft Store
- Un accès
sudo
WSL1 vs WSL2 Assurez-vous d'utiliser WSL2 et non WSL1. Docker rootless et les performances réseau sont bien meilleurs sous WSL2. Vérifiez avec wsl -l -v depuis PowerShell.
Première installation ? Si Docker était déjà installé sur le système, désinstallez les anciennes versions avant de commencer :
sudo apt remove docker docker-engine docker.io containerd runc01. Mise à jour du système
Avant toute chose, on s'assure que le système est à jour.
sudo apt update
sudo apt upgradeAucune erreur ne doit apparaître. Si apt update échoue, vérifiez votre connexion réseau avec ping 8.8.8.8.
02. Installation de bash-completion
Pour profiter de l'autocomplétion dans le terminal.
sudo apt install bash-completionVérifiez ensuite que les lignes suivantes sont présentes et décommentées dans votre ~/.bashrc :
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fisource ~/.bashrcTapez docker puis appuyez sur Tab — vous devriez voir les sous-commandes s'afficher (après l'installation de Docker).
Tip — Zsh Pour une autocomplétion encore plus puissante (suggestions en grisé, complétion git, docker…), envisagez Zsh avec Oh My Zsh :
sudo apt install zsh && sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"03. Création des utilisateurs et groupes
On crée un utilisateur dédié à Docker ainsi qu'un groupe developers pour gérer les accès proprement.
sudo adduser admin_docker
sudo groupadd developers
sudo usermod -aG developers admin_docker
sudo usermod -aG developers developerOn crée également le répertoire de données des conteneurs :
sudo mkdir -p /opt/docker-dataPourquoi un utilisateur dédié ? Séparer l'utilisateur qui fait tourner Docker de votre utilisateur courant est une bonne pratique de sécurité, surtout en mode rootless. Cela isole clairement les permissions et les données Docker.
getent group developers04. Installation des dépendances
Dépendances de base
sudo apt install curl wget gnupg ca-certificates lsb-release -yDépendances pour Docker rootless et le réseau
sudo apt install apt-transport-https uidmap dbus-user-session fuse-overlayfs slirp4netns iproute2 iptables acl systemd-containerÀ quoi servent ces paquets ?
uidmap— remappage des UIDs pour le mode rootlessfuse-overlayfs— driver de système de fichiers pour rootlessslirp4netns— réseau en espace utilisateur pour rootlessdbus-user-session— nécessaire pour systemd useracl— gestion fine des permissions sur les fichiers
05. Ajout de la clé GPG Docker
Cette étape configure le dépôt officiel Docker avec vérification GPG, ce qui garantit que les paquets téléchargés sont authentiques et n'ont pas été modifiés.
sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpgVérifiez que l'empreinte correspond bien à la clé officielle Docker :
gpg --show-keys /usr/share/keyrings/docker-archive-keyring.gpgL'empreinte officielle Docker est : 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
ls -lh /usr/share/keyrings/docker-archive-keyring.gpgErreur possible Si curl échoue avec une erreur SSL, vérifiez que ca-certificates est bien installé :
sudo apt install --reinstall ca-certificates06. Ajout du dépôt Docker
On ajoute le dépôt officiel Docker correspondant à votre architecture et version de Debian.
echo "deb [arch=$(dpkg --print-architecture) \
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/nullcat /etc/apt/sources.list.d/docker.listVous devriez voir :
deb [arch=amd64 signed-by=...docker-archive-keyring.gpg] https://download.docker.com/linux/debian trixie stableErreurs classiques dans cette commande
- Simples quotes
'...'au lieu de doubles"..."— les substitutions$(...)ne s'exécutent pas - Écrire
${dpkg ...}au lieu de$(dpkg ...)— mélange des syntaxes - Faute de frappe :
/usr/share/keyring/au lieu de/usr/share/keyrings/(avec un s)
07. Installation de Docker
On met à jour la liste des paquets pour inclure le nouveau dépôt, puis on installe Docker et ses plugins.
sudo apt update
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-ce-rootless-extras \
uidmap \
dbus-user-sessionÀ quoi servent ces paquets ?
docker-ce— le démon Docker (Community Edition)docker-ce-cli— l'outil en ligne de commandedockercontainerd.io— le runtime de conteneursdocker-buildx-plugin— builds multi-architecturedocker-ce-rootless-extras— outils nécessaires au mode rootless
08. Vérification de l'installation
docker --version
docker compose versionDocker version 29.3.0, build ...
Docker Compose version v5.1.109. Ajout de l'utilisateur au groupe Docker
On ajoute admin_docker au groupe docker pour lui permettre d'exécuter des commandes Docker sans sudo.
sudo usermod -aG docker admin_dockerCe changement de groupe ne prend effet qu'à la prochaine connexion de l'utilisateur. Il suffit d'ouvrir un nouveau shell.
groups admin_dockerConfiguration du mode rootless
10. Configuration des UIDs/GIDs subordonnés
Ces plages permettent au démon Docker rootless de mapper les utilisateurs à l'intérieur des conteneurs sans avoir besoin de droits root.
echo "admin_docker:100000:65536" | sudo tee -a /etc/subuid
echo "admin_docker:100000:65536" | sudo tee -a /etc/subgidLa valeur 65536 représente le nombre d'UIDs réservés (de 100000 à 165535). C'est la plage standard recommandée par Docker.
Activation du linger
Le linger permet aux services systemd de l'utilisateur de démarrer automatiquement sans qu'il soit connecté.
sudo loginctl enable-linger admin_dockerDésactivation du Docker root
On désactive le service Docker root pour n'utiliser que la version rootless.
sudo systemctl disable --now docker.service docker.socket11. Vérifications de la configuration rootless
grep admin_docker /etc/subuid /etc/subgidRésultat attendu :
/etc/subuid:admin_docker:100000:65536
/etc/subgid:admin_docker:100000:65536loginctl show-user admin_docker | grep LingerRésultat attendu : Linger=yes
12. Basculer vers l'utilisateur admin_docker
On utilise machinectl pour ouvrir un shell complet en tant que admin_docker, avec son environnement systemd user correctement initialisé.
sudo machinectl shell admin_docker@Pourquoi machinectl et pas su ? su - admin_docker n'initialise pas correctement l'environnement systemd user (notamment XDG_RUNTIME_DIR). machinectl shell ouvre une vraie session utilisateur complète, indispensable pour Docker rootless.
echo $XDG_RUNTIME_DIRVous devriez obtenir quelque chose comme /run/user/1002.
Si XDG_RUNTIME_DIR est vide Le linger n'est pas actif ou la session n'est pas correctement initialisée. Relancez : sudo loginctl enable-linger admin_docker
13. Installation de Docker rootless
On lance le script d'installation rootless depuis la session admin_docker.
dockerd-rootless-setuptool.sh installErreur — socket rootful encore présent Si vous obtenez [ERROR] Aborting because rootful Docker (/var/run/docker.sock) is running and accessible, le socket est encore présent sur le disque. Supprimez-le et relancez :
sudo rm /var/run/docker.sock
dockerd-rootless-setuptool.sh install14. Configuration des variables d'environnement
Pour que les commandes docker utilisent bien le socket rootless, ajoutez ces variables dans le ~/.bashrc de admin_docker.
cat >> ~/.bashrc << 'EOF'
# Docker Rootless
export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
EOF
source ~/.bashrcSans DOCKER_HOST, le client Docker cherche par défaut /var/run/docker.sock (le socket root). Cette variable lui indique d'utiliser le socket de l'utilisateur courant.
15. Démarrage automatique de Docker rootless
systemctl --user enable docker
systemctl --user start dockerErreur — Unit docker.service does not exist Les variables d'environnement ne sont pas encore chargées. Définissez-les manuellement, rechargez systemd, puis réessayez :
export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
systemctl --user daemon-reload
systemctl --user enable docker
systemctl --user start dockerPour éviter ce problème à chaque reconnexion, assurez-vous que les variables sont dans ~/.bashrc (voir étape 14).
systemctl --user status dockerVous devriez voir active (running).
16. Vérification finale
docker info
docker info | grep -i rootless✅ Points importants à vérifier
Warning cgroups (normal sous WSL2)
WARNING: Running in rootless-mode without cgroups...
WARNING: Support for cgroup v1 is deprecated... May 2029Ce warning est sans conséquence immédiate. Pour l'éliminer, activez cgroup v2 dans %USERPROFILE%\.wslconfig sous Windows :
[wsl2]
kernelCommandLine = cgroup_no_v1=allPuis : wsl --shutdown. Vérifiez avec cat /sys/fs/cgroup/cgroup.controllers.
⚠️ Cette modification affecte toutes vos distributions WSL.
17. Premier test
On vérifie que Docker est pleinement fonctionnel en lançant le conteneur de test officiel.
docker run --rm hello-worldSi vous voyez le message Hello from Docker! , l'installation est complète et opérationnelle.
L'option --rm supprime automatiquement le conteneur après son exécution. Utile pour les tests ponctuels afin de ne pas accumuler des conteneurs stoppés.
Configuration des permissions et réseaux
18. Permissions des données Docker
On configure le répertoire qui contiendra les données persistantes des conteneurs (volumes).
sudo chown -R admin_docker:developers /opt/docker-data/ignis/
sudo chmod -R 2775 /opt/docker-data/ignis/Comprendre le 2775
2(setgid) — tout nouveau fichier héritera automatiquement du groupedevelopers7— lecture, écriture, exécution pour le propriétaire7— lecture, écriture, exécution pour le groupe5— lecture et exécution pour les autres (pas d'écriture)
ls -la /opt/docker-data/Vous devriez voir drwxrwsr-x (le s indique que le setgid est actif).
19. Configuration sécurisée du démon Docker
On crée un fichier daemon.json pour appliquer des paramètres de sécurité et de logs au démon Docker rootless.
mkdir -p ~/.config/docker
cat > ~/.config/docker/daemon.json << 'EOF'
{
"storage-driver": "fuse-overlayfs",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"no-new-privileges": true,
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65536,
"Soft": 65536
}
}
}
EOF
systemctl --user restart dockerÀ quoi servent ces paramètres ?
storage-driver: fuse-overlayfs— driver optimisé pour le mode rootlesslog-driver + log-opts— limite la taille des logs (3 fichiers de 10 Mo max)no-new-privileges— empêche les conteneurs d'acquérir de nouveaux privilègesdefault-ulimits— définit une limite raisonnable du nombre de fichiers ouverts
20. Création des réseaux Docker
On crée deux réseaux distincts selon leur rôle.
Réseau partagé — traefik-network
Réseau sur lequel Traefik sera connecté. Les conteneurs accessibles depuis l'extérieur y sont rattachés.
docker network create \
--driver bridge \
--subnet 172.247.193.0/24 \
--gateway 172.247.193.254 \
--opt com.docker.network.bridge.name=traefik-br \
--opt com.docker.network.driver.mtu=1500 \
traefik-networkRéseau isolé — ignis-network
Réseau --internal : aucun trafic entrant/sortant vers l'extérieur. Uniquement pour les services backend (BDD, cache…).
docker network create \
--driver bridge \
--internal \
--subnet 172.247.194.0/24 \
--gateway 172.247.194.254 \
--opt com.docker.network.bridge.name=ignis-br \
ignis-networkexternal: true vs --internal Ce sont deux concepts distincts : external: true dans le compose signifie que le réseau existe déjà (créé manuellement). --internal signifie que le réseau est isolé d'internet. Les deux s'appliquent en même temps pour ignis-network.
docker network ls
docker network inspect traefik-network
docker network inspect ignis-network21. Redémarrage
On redémarre pour s'assurer que toutes les modifications (groupes, linger, systemd) sont bien prises en compte.
sudo rebootWSL Sous WSL, sudo reboot ferme simplement la session. Relancez votre terminal Windows. Vous pouvez aussi faire wsl --shutdown depuis PowerShell.
Commandes utiles au quotidien
Conteneurs
docker ps # Lister les conteneurs en cours d'exécution
docker ps -a # Lister tous les conteneurs (y compris stoppés)
docker start <nom> # Démarrer un conteneur stoppé
docker stop <nom> # Arrêter un conteneur
docker restart <nom> # Redémarrer un conteneur
docker rm <nom> # Supprimer un conteneur stoppé
docker rm -f <nom> # Forcer la suppression (même si actif)
docker logs <nom> # Afficher les logs d'un conteneur
docker logs -f <nom> # Suivre les logs en temps réel
docker exec -it <nom> bash # Ouvrir un shell dans un conteneur actif
docker inspect <nom> # Afficher toutes les infos d'un conteneur
docker stats # Voir la consommation CPU/RAM en temps réelImages
docker images # Lister les images locales
docker pull <image> # Télécharger une image
docker rmi <image> # Supprimer une image
docker image prune # Supprimer les images non utilisées
docker scout cves <image> # Scanner une image pour les vulnérabilitésVolumes
docker volume ls # Lister les volumes
docker volume inspect <nom> # Détails d'un volume
docker volume rm <nom> # Supprimer un volume
docker volume prune # Supprimer les volumes non utilisés
# Sauvegarder un volume
docker run --rm \
-v <nom-volume>:/data \
-v $(pwd):/backup \
alpine tar czf /backup/backup.tar.gz /dataNettoyage
docker system df # Voir l'espace utilisé par Docker
docker system prune # Supprimer conteneurs, images et réseaux non utilisés
docker system prune -a --volumes # Nettoyage complet (attention, irréversible)Docker Compose
docker compose up -d # Démarrer les services en arrière-plan
docker compose down # Arrêter et supprimer les conteneurs
docker compose down -v # Idem + suppression des volumes
docker compose ps # État des services
docker compose logs -f # Suivre les logs de tous les services
docker compose pull # Mettre à jour les images
docker compose restart # Redémarrer les servicesRéseaux
docker network ls # Lister tous les réseaux
docker network inspect <nom> # Détails d'un réseau
docker network create <nom> # Créer un réseau bridge simple
docker network rm <nom> # Supprimer un réseau
docker network prune # Supprimer les réseaux non utilisés
docker network connect <réseau> <conteneur> # Connecter un conteneur
docker network disconnect <réseau> <conteneur> # Déconnecter un conteneur
ip link show # Voir les interfaces réseauService Docker rootless
systemctl --user status docker # État du service Docker
systemctl --user restart docker # Redémarrer le démon Docker
systemctl --user stop docker # Arrêter le démon Docker
journalctl --user -u docker # Logs du démon DockerErreurs fréquentes et solutions
| Erreur | Cause | Solution |
|---|---|---|
permission denied /var/run/docker.sock | Utilisateur pas dans le groupe docker | sudo usermod -aG docker $USER puis reconnexion |
Cannot connect to the Docker daemon | Le démon Docker n'est pas démarré | systemctl --user start docker |
XDG_RUNTIME_DIR not set | Session mal initialisée | Utiliser machinectl shell au lieu de su |
rootful Docker is running and accessible | Socket /var/run/docker.sock présent | sudo rm /var/run/docker.sock |
| Tab ne complète pas | bash-completion absent ou non chargé | sudo apt install bash-completion + vérifier ~/.bashrc |
lsb_release: command not found | Paquet absent | sudo apt install lsb-release |
DOCKER_HOST non défini | Variables d'env manquantes | Vérifier ~/.bashrc et relancer source ~/.bashrc |
Checklist de sécurité
- Docker Rootless installé et fonctionnel (
docker info | grep rootless) - Dépôt officiel avec clé GPG vérifiée
-
no-new-privilegesactivé dansdaemon.json - Logs limités (
max-size,max-file) dansdaemon.json - Conteneurs tournant avec un utilisateur non-root
- Filesystem
read_onlyactivé là où c'est possible - Réseaux isolés pour le backend (
--internal) - Secrets dans
.env(non commité dans git) - Health checks configurés sur les conteneurs critiques
- Images scannées pour les vulnérabilités (
docker scout cves) - Sauvegardes des volumes en place