🎯 Compétences acquises
Maîtriser Docker sur Linux
🛠️ Le Tutoriel Complet
Docker sur Ubuntu Linux
La métaphore d'OWL : Les Containers de Cargo
Un conteneur Docker, c'est exactement comme un container de cargo maritime. L'image Docker, c'est le plan de construction du container — tu peux en créer autant d'exemplaires que tu veux. Le conteneur, c'est le container physique en cours de transport, avec tout ce dont l'application a besoin à l'intérieur (code, dépendances, configuration).
Le génie du système : peu importe le bateau (ton serveur Ubuntu, un Mac, Windows, le cloud AWS), le container s'ouvre et fonctionne exactement pareil. "It works on my machine" n'existe plus — si ça marche dans le container, ça marche partout.
Docker Compose, c'est le manifeste de cargo : un seul document YAML qui dit "sur ce bateau, il y a 3 containers à un Nginx, un PostgreSQL, et un Nextcloud — et voilé comment ils communiquent entre eux".
1. Installer Docker sur Ubuntu
Installation officielle depuis les dépôts Docker (plus récent que le paquet Ubuntu) :
sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null
# Installer les dépendances
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# Ajouter la clé GPG officielle Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Ajouter le dépôt Docker
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# Installer Docker Engine + Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Vérifier l'installation
docker --version
docker compose version
Docker version 27.x.x, build...
Docker Compose version v2.x.x
# Ajouter ton utilisateur au groupe docker (pas besoin de sudo)
sudo usermod -aG docker $USER
newgrp docker # activer sans déconnexion
# Tester
docker run hello-world
Après sudo usermod -aG docker $USER, tu dois te déconnecter/reconnecter (ou relancer le terminal) pour que le groupe prenne effet. La commande newgrp docker l'active temporairement sans déconnexion.
2. Images, Conteneurs, Volumes & Réseaux
Architecture Docker :
Docker Hub (Registry)
é
— docker pull
?
Image nginx:latest ---- immuable, lecture seule
é
— docker run
?
+-------------------------------------+
é Conteneur nginx é
é +-- Couche image (lecture seule) é
é +-- Couche conteneur (écriture) — — données perdues à l'arrêt !
é é
é Port: 80 ------------------------ é--é Port hôte: 8080
+-------------------------------------+
é
— bind mount / volume
?
Volume Docker / Dossier hôte ---- persistant é
docker images # lister les images locales
docker pull nginx # télécharger une image
docker pull nginx:1.25 # version spécifique
docker rmi nginx # supprimer une image
docker image prune # supprimer les images inutilisées
## CONTENEURS ##
docker ps # conteneurs en cours
docker ps -a # tous les conteneurs (même arrêtés)
docker start mon_conteneur # démarrer
docker stop mon_conteneur # arrêter proprement
docker restart mon_conteneur # redémarrer
docker rm mon_conteneur # supprimer un conteneur arrêté
docker logs -f mon_conteneur # voir les logs en direct
docker exec -it mon_conteneur bash # ouvrir un shell dans le conteneur
docker inspect mon_conteneur # informations détaillées
## VOLUMES ##
docker volume ls # lister les volumes
docker volume create mes_data # créer un volume nommé
docker volume rm mes_data # supprimer un volume
docker volume prune # supprimer les volumes orphelins
## NETTOYAGE GLOBAL ##
docker system prune -a # tout nettoyer (containers + images)
docker system df # espace utilisé par Docker
3. docker run — Maîtriser les Options
docker run \
--name mon_nginx \ # nommer le conteneur
-d \ # detached (tourne en arrière-plan)
-p 8080:80 \ # port hôte:port_conteneur
-v /opt/nginx/html:/usr/share/nginx/html \ # bind mount
-e MON_VAR="valeur" \ # variable d'environnement
--restart unless-stopped \ # redémarrer auto (sauf si arrêt manuel)
--network mon_reseau \ # rôleau Docker
nginx:latest # image:tag
# Politique --restart :
# no = jamais (défaut)
# always = toujours, même au reboot
# unless-stopped = toujours sauf si arrêté manuellement — recommandé
# on-failure = seulement en cas d'erreur
# Exemples concrets
docker run -d --name nginx -p 80:80 --restart unless-stopped nginx
docker run -d --name whoami -p 8000:80 traefik/whoami
docker run -it --rm ubuntu bash # shell interactif, supprimé à la fermeture
4. Docker Compose — Orchestration Multi-Services
Docker Compose te permet de définir et gérer plusieurs conteneurs dans un seul fichier compose.yml. C'est la méthode de référence pour le self-hosting.
cd /opt/mon_service/
docker compose up -d # démarrer tous les services en arrière-plan
docker compose down # arrêter et supprimer les conteneurs
docker compose down -v # + supprimer les volumes
docker compose restart # redémarrer tous les services
docker compose pull # mettre à jour les images
docker compose ps # statut des services
docker compose logs -f # logs en direct de tous les services
docker compose logs -f nginx # logs d'un service spécifique
docker compose exec nginx bash # shell dans un service
Structure d'un compose.yml :
webapp: # nom du service
image: nginx:latest # image Docker Hub
container_name: mon_nginx # nom du conteneur
restart: unless-stopped # politique de redémarrage
ports:
- "80:80" # hôte:conteneur
- "443:443"
volumes:
- ./html:/usr/share/nginx/html # bind mount (chemin relatif)
- nginx_logs:/var/log/nginx # volume nommé
environment:
- TZ=Europe/Paris # variable d'env
networks:
- frontend
depends_on:
- db # attendre que db soit prêt
db: # deuxiéme service
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: owl
POSTGRES_PASSWORD: secret123
POSTGRES_DB: mabase
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- frontend
volumes: # volumes nommés déclarés ici
nginx_logs:
postgres_data:
networks: # rôleaux personnalisés
frontend:
driver: bridge
5. Stacks Docker Compose Prêtes à l'Emploi
Portainer — Interface Graphique Docker
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
ports:
- "9000:9000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:
# Déployer :
mkdir -p /opt/portainer && cd /opt/portainer
# Colle le compose.yml ci-dessus, puis :
docker compose up -d
# Accès — http://localhost:9000
WordPress + MariaDB — Stack Complète
wordpress:
image: wordpress:latest
container_name: wordpress
restart: unless-stopped
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: owl
WORDPRESS_DB_PASSWORD: motdepasse_fort
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
depends_on:
- db
db:
image: mariadb:11
container_name: wordpress_db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root_secret
MYSQL_DATABASE: wordpress
MYSQL_USER: owl
MYSQL_PASSWORD: motdepasse_fort
volumes:
- db_data:/var/lib/mysql
volumes:
wordpress_data:
db_data:
Uptime Kuma — Monitoring de Services
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- uptime_data:/app/data
environment:
- TZ=Europe/Paris
volumes:
uptime_data:
# Accès — http://localhost:3001
6. Créer sa Propre Image — Dockerfile
Un Dockerfile est la recette pour construire une image Docker personnalisée. Exemple avec une app Python simple :
FROM python:3.12-slim
# Métadonnées
LABEL maintainer="owl@owlnetgeek.fr"
# Définir le dossier de travail dans le conteneur
WORKDIR /app
# Copier et installer les dépendances D'ABORD (optimisation cache)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copier le code source
COPY . .
# Exposer le port
EXPOSE 8000
# Utilisateur non-root pour la sécurité
RUN useradd -m appuser && chown -R appuser /app
USER appuser
# Commande de démarrage
CMD ["python", "app.py"]
# Construire l'image
docker build -t mon_app:1.0 .
# Lancer le conteneur
docker run -d -p 8000:8000 mon_app:1.0
7. Mettre — Jour ses Conteneurs
cd /opt/mon_service
docker compose pull # télécharger les nouvelles images
docker compose up -d # recréer les conteneurs avec les nouvelles images
docker image prune -f # nettoyer les anciennes images
# Méthode docker run simple
docker pull nginx:latest
docker stop mon_nginx
docker rm mon_nginx
docker run -d --name mon_nginx -p 80:80 --restart unless-stopped nginx:latest
# Watchtower — Mise à jour automatique des conteneurs
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
--schedule "0 0 3 * * *" \ # tous les jours — 3h
--cleanup # nettoyer les anciennes images
Le Setup Docker d'OWL — Organisation des Stacks
OWL organise ses services Docker dans des dossiers dédiés sous /opt/ :
+-- portainer/ — gestion graphique Docker
é +-- compose.yml
+-- nginx-proxy/ — reverse proxy + SSL
é +-- compose.yml
é +-- conf.d/
+-- jellyfin/ — streaming vidéo
é +-- compose.yml
+-- nextcloud/ — cloud personnel
é +-- compose.yml
+-- uptime-kuma/ — monitoring
é +-- compose.yml
+-- vaultwarden/ — gestionnaire de mots de passe
+-- compose.yml
# Script de MAJ globale de tous les services
for SERVICE in /opt/*/; do
if [ -f "$SERVICE/compose.yml" ]; then
echo "💡 Mise à jour : $SERVICE"
cd "$SERVICE" && docker compose pull -q && docker compose up -d -q
fi
done
docker image prune -f
echo "é Tous les services sont à jour !"
✅ Comment savoir si tu maîtrises Docker
- ✅Docker est installé et
docker run hello-worldaffiche le message de succès - ✅Tu as déployé Portainer avec Docker Compose et tu peux voir tes conteneurs via l'interface web
- ✅Tu comprends la différence entre une image (plan) et un conteneur (instance), et entre volume nommé et bind mount
- ✅Tu as déployé un stack multi-services avec Docker Compose (ex: WordPress + MariaDB) et les deux services communiquent
- ✅Tu sais mettre à jour un service avec
docker compose pull && docker compose up -dsans perdre ses données
⚠️ Problèmes Courants & Solutions
"Permission denied" quand j'utilise docker sans sudo
💡 Tu n'es pas encore dans le groupe docker. Lance sudo usermod -aG docker $USER puis déconnecte-toi/reconnecte-toi. Vérifie avec groups que "docker" apparaît dans la liste.
Mon conteneur redémarre en boucle
💡 Regarde les logs ! docker logs --tail 50 mon_conteneur. Les causes fréquentes : variable d'environnement manquante, port déjé utilisé par un autre service, volume avec des permissions incorrectes, ou image incompatible avec l'architecture CPU.
"Port already in use" au démarrage d'un conteneur
💡 Un autre service utilise déjé ce port. Identifie-le avec sudo ss -tlnp | grep :80 ou sudo lsof -i :80. Tu peux changer le port hôte dans le compose.yml (ex: "8080:80" au lieu de "80:80").
Docker utilise trop d'espace disque
🐳 Docker accumule images, conteneurs et volumes inutilisés. Vois l'utilisation avec docker system df. Nettoie avec : docker image prune -a (images), docker container prune (conteneurs arrêtés), docker volume prune (volumes orphelins). Ou tout d'un coup : docker system prune -a 💡 attention aux volumes !