Docker est une plateforme de conteneurisation qui permet de packager une application et ses dépendances dans un conteneur isolé, garantissant qu'elle fonctionne de manière identique dans tous les environnements.

🎯 Avantages de Docker :
  • Portabilité : "Fonctionne sur ma machine" devient universel
  • Isolation : Chaque conteneur est isolé
  • Légèreté : Plus rapide et moins lourd que les VMs
  • Scalabilité : Facile à dupliquer et orchestrer
  • Reproductibilité : Environnements identiques

Installation

Linux (Ubuntu/Debian)

Bash
# Installer Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Ajouter utilisateur au groupe docker
sudo usermod -aG docker $USER

# Vérifier l'installation
docker --version
docker run hello-world

Windows / macOS

Télécharger Docker Desktop depuis docker.com

Commandes de Base

Gestion des conteneurs

Bash
# Lister les conteneurs actifs
docker ps

# Lister tous les conteneurs (actifs et arrêtés)
docker ps -a

# Démarrer un conteneur
docker run nginx                    # Mode attached
docker run -d nginx                 # Mode détaché (background)
docker run -d --name mon-nginx nginx  # Avec nom personnalisé

# Arrêter un conteneur
docker stop mon-nginx

# Redémarrer un conteneur
docker restart mon-nginx

# Supprimer un conteneur
docker rm mon-nginx
docker rm -f mon-nginx             # Forcer la suppression

# Voir les logs
docker logs mon-nginx
docker logs -f mon-nginx           # Suivre les logs en temps réel

# Exécuter une commande dans un conteneur
docker exec -it mon-nginx bash    # Ouvrir un shell interactif

Gestion des images

Bash
# Lister les images locales
docker images

# Télécharger une image
docker pull nginx:latest
docker pull mysql:8.0

# Supprimer une image
docker rmi nginx:latest

# Construire une image depuis un Dockerfile
docker build -t mon-app:1.0 .

# Tag d'une image
docker tag mon-app:1.0 mon-app:latest

# Push vers un registry
docker push username/mon-app:1.0

# Inspecter une image
docker inspect nginx:latest

Dockerfile

Exemple basique (Node.js)

Dockerfile
# Image de base
FROM node:18-alpine

# Définir le répertoire de travail
WORKDIR /app

# Copier package.json et package-lock.json
COPY package*.json ./

# Installer les dépendances
RUN npm ci --only=production

# Copier le code source
COPY . .

# Exposer le port
EXPOSE 3000

# Créer un utilisateur non-root
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

# Commande de démarrage
CMD ["node", "server.js"]

Exemple multi-stage (optimisé)

Dockerfile
# Stage 1 : Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2 : Production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
USER node
CMD ["node", "dist/index.js"]

Instructions Dockerfile courantes

Dockerfile
FROM ubuntu:22.04              # Image de base
LABEL maintainer="email@example.com"  # Métadonnées

ENV NODE_ENV=production        # Variables d'environnement
ARG BUILD_VERSION=1.0          # Arguments de build

WORKDIR /app                   # Répertoire de travail
COPY . .                       # Copier fichiers
ADD archive.tar.gz /app        # Copier et extraire

RUN apt-get update && \        # Exécuter commandes
    apt-get install -y curl

EXPOSE 8080                    # Port exposé
VOLUME /data                   # Point de montage volume

USER appuser                   # Utilisateur d'exécution
CMD ["./app"]                  # Commande par défaut
ENTRYPOINT ["./entrypoint.sh"] # Point d'entrée

Volumes et Persistence

Bash
# Créer un volume
docker volume create mon-volume

# Lister les volumes
docker volume ls

# Monter un volume dans un conteneur
docker run -d -v mon-volume:/data nginx

# Bind mount (lier un dossier local)
docker run -d -v /home/user/data:/data nginx
docker run -d -v $(pwd):/app node

# Supprimer un volume
docker volume rm mon-volume

# Nettoyer les volumes non utilisés
docker volume prune

Réseaux

Bash
# Créer un réseau
docker network create mon-reseau

# Lister les réseaux
docker network ls

# Connecter un conteneur à un réseau
docker run -d --network mon-reseau --name web nginx

# Inspecter un réseau
docker network inspect mon-reseau

# Les conteneurs sur le même réseau peuvent communiquer par nom
docker run -d --network mon-reseau --name db postgres
# "web" peut accéder à "db" via : http://db:5432

Docker Compose

docker-compose.yml - Stack LAMP

YAML
version: '3.8'

services:
  # Apache + PHP
  web:
    image: php:8.2-apache
    container_name: web-server
    ports:
      - "80:80"
    volumes:
      - ./src:/var/www/html
    depends_on:
      - db
    networks:
      - app-network
    environment:
      - MYSQL_HOST=db
      - MYSQL_USER=root
      - MYSQL_PASSWORD=secret
    restart: unless-stopped

  # MySQL
  db:
    image: mysql:8.0
    container_name: mysql-db
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    networks:
      - app-network
    restart: unless-stopped

  # phpMyAdmin
  phpmyadmin:
    image: phpmyadmin:latest
    container_name: phpmyadmin
    ports:
      - "8080:80"
    environment:
      PMA_HOST: db
      PMA_USER: root
      PMA_PASSWORD: secret
    depends_on:
      - db
    networks:
      - app-network

volumes:
  db-data:

networks:
  app-network:
    driver: bridge

Commandes Docker Compose

Bash
# Démarrer tous les services
docker-compose up
docker-compose up -d              # En arrière-plan

# Arrêter les services
docker-compose down
docker-compose down -v            # Supprimer aussi les volumes

# Voir les logs
docker-compose logs
docker-compose logs -f web        # Suivre les logs d'un service

# Reconstruire les images
docker-compose build
docker-compose up --build

# Lister les services
docker-compose ps

# Exécuter une commande
docker-compose exec web bash

# Redémarrer un service
docker-compose restart web

Stack complète avec Node.js + MongoDB + Redis

YAML
version: '3.8'

services:
  app:
    build: .
    container_name: node-app
    ports:
      - "3000:3000"
    volumes:
      - ./src:/app/src
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - MONGODB_URI=mongodb://mongo:27017/mydb
      - REDIS_URL=redis://redis:6379
    depends_on:
      - mongo
      - redis
    networks:
      - app-network

  mongo:
    image: mongo:7
    container_name: mongodb
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: password
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    container_name: redis-cache
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app
    networks:
      - app-network

volumes:
  mongo-data:
  redis-data:

networks:
  app-network:
    driver: bridge

Bonnes Pratiques

✅ Sécurité et optimisation :
  • .dockerignore : Exclure fichiers inutiles (.git, node_modules, etc.)
  • Images légères : Utiliser alpine quand possible
  • Multi-stage builds : Réduire la taille de l'image finale
  • Layer caching : Ordonner les instructions pour optimiser le cache
  • Utilisateur non-root : Ne pas exécuter en tant que root
  • Scanner les vulnérabilités : docker scan image-name
  • Versions spécifiques : Éviter :latest en production
  • Secrets : Ne jamais hardcoder dans les images
  • Health checks : Définir des HEALTHCHECK
  • Logs : Logger vers stdout/stderr

Exemple .dockerignore

Plaintext
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.local
.DS_Store
dist
coverage
*.log

Dépannage

Bash
# Voir l'utilisation des ressources
docker stats

# Inspecter un conteneur
docker inspect mon-conteneur

# Voir les processus dans un conteneur
docker top mon-conteneur

# Nettoyer tout (ATTENTION!)
docker system prune -a --volumes

# Libérer de l'espace
docker image prune          # Supprimer images non utilisées
docker container prune      # Supprimer conteneurs arrêtés
docker volume prune         # Supprimer volumes non utilisés
docker network prune        # Supprimer réseaux non utilisés

# Analyser l'espace disque
docker system df

# Copier des fichiers depuis/vers un conteneur
docker cp mon-conteneur:/app/log.txt ./log.txt
docker cp ./config.json mon-conteneur:/app/

# Exporter/Importer une image
docker save -o mon-image.tar mon-image:latest
docker load -i mon-image.tar

Ressources