1. Conteneurs et machines virtuelles #
Isoler sans virtualiser un système entier.
Le principe #
Un conteneur est un processus isolé grâce aux namespaces (vue propre des processus, du réseau, des fichiers) et limité par les cgroups (CPU, mémoire). Il démarre en quelques secondes, pèse quelques dizaines de Mo et garantit que « ça marche chez moi » signifie « ça marche partout ».
| Critère | Machine virtuelle | Conteneur |
|---|---|---|
| Démarrage | Minutes | Secondes |
| Taille | Go | Mo |
| Isolation | Forte (hyperviseur) | Processus (noyau partagé) |
| Densité | Dizaines par hôte | Centaines par hôte |
2. L'architecture de Docker #
Images, conteneurs, registres.
Les briques #
- Image : modèle en lecture seule, construit en couches empilées.
- Conteneur : instance en cours d'exécution d'une image (avec une couche en écriture).
- Registry : dépôt d'images (Docker Hub, GHCR, registre privé).
- Volume : stockage persistant hors du cycle de vie du conteneur.
docker version && docker info | head -20
docker run hello-world # télécharge et exécute une image de test
docker images && docker ps -a3. Les commandes essentielles #
Cycle de vie d'un conteneur.
Lancer et gérer #
docker run -d --name web -p 8080:80 -e TZ=Europe/Paris --restart unless-stopped nginx:1.27
docker run -it --rm alpine sh # shell jetable
docker ps / docker ps -a # conteneurs en cours / tous
docker logs -f --tail 50 web
docker exec -it web sh
docker stop web && docker start web && docker restart web
docker rm -f web # supprimer un conteneur
docker stats --no-stream # consommation CPU/mémoire
docker inspect web | jq '.[0].NetworkSettings.IPAddress'
docker cp web:/etc/nginx/nginx.conf ./nginx.conf
docker pull nginx:1.27 && docker images
docker image prune -a && docker system prune --volumes # nettoyer (attention !)
docker system df # espace utilisé4. Construire ses images et orchestrer en local #
Dockerfile, volumes, réseaux, Compose.
Dockerfile #
# Dockerfile (application Python)
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER 10001
EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]docker build -t mon-app:1.0 .
docker run -d -p 8000:8000 mon-app:1.0
docker tag mon-app:1.0 registre.exemple.fr/equipe/mon-app:1.0 && docker push registre.exemple.fr/equipe/mon-app:1.0
docker history mon-app:1.0 # couches et taillesBonne Pratique : Ordonnez les instructions du moins changeant au plus changeant (dépendances avant le code) pour profiter du cache de couches ; utilisez des builds multi-étapes pour des images finales minuscules.
Volumes, réseaux et Compose #
docker volume create pgdata
docker network create backend
docker run -d --name db --network backend -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret postgres:16
docker run -d --name api --network backend -p 8000:8000 -e DB_HOST=db mon-app:1.0 # "db" résolu par DNS# compose.yaml
services:
api:
build: .
ports: ["8000:8000"]
environment: { DB_HOST: db }
depends_on: { db: { condition: service_healthy } }
db:
image: postgres:16
environment: { POSTGRES_PASSWORD: secret }
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck: { test: ["CMD-SHELL", "pg_isready -U postgres"], interval: 5s, retries: 10 }
volumes: { pgdata: {} }docker compose up -d --build
docker compose ps && docker compose logs -f api
docker compose down -v