Standardiser l'environnement de développement avec Docker Compose pour des builds fiables et un onboarding plus rapide.
Introduction et concepts Docker
Docker est une plateforme de containerization qui empaquète votre application et toutes ses dépendances dans un conteneur isolé et reproductible.
Concepts clés :
- Image : template read-only avec application + dépendances
- Container : instance en cours d'exécution d'une image
- Dockerfile : instructions pour construire une image
- Docker Compose : orchestrer plusieurs conteneurs (dev local)
- Registry : hub centralisant les images (Docker Hub)
Avantages pour le dev :
- Isolation complète : pas de conflits de dépendances
- Environnement identique : dev, test, production
- Setup rapide : `docker-compose up` au lieu d'installer 10 logiciels
- Scalabilité : multiplier les instances en secondes
Installation et premier conteneur
Installation :
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io docker-compose
# Ajouter l'utilisateur au groupe docker
sudo usermod -aG docker $USER
newgrp docker # Activer sans redémarrage
Premier conteneur (Nginx) :
docker run -d -p 8080:80 --name my-nginx nginx
# Vérifier
docker ps
curl http://localhost:8080
# Arrêter et supprimer
docker stop my-nginx
docker rm my-nginx
Commandes de base :
docker images # Lister les images locales
docker ps # Conteneurs en cours
docker ps -a # Tous les conteneurs
docker logs my-nginx # Logs du conteneur
docker exec -it my-nginx bash # Accéder au conteneur
docker inspect my-nginx # Détails du conteneur
Créer un Dockerfile
Dockerfile pour une app Node.js :
FROM node:18-alpine
# Définir le répertoire de travail
WORKDIR /app
# Copier package.json et installer les dépendances
COPY package*.json ./
RUN npm install
# Copier le code de l'app
COPY . .
# Exposer le port
EXPOSE 3000
# Commande de démarrage
CMD ["npm", "start"]
Build et run :
docker build -t my-app:1.0 .
docker run -p 3000:3000 my-app:1.0
Best practices dans Dockerfile :
- Utiliser des images de base légères (alpine, slim)
- Multi-stage builds pour réduire la taille finale
- Ne pas exécuter en root (USER node)
- .dockerignore pour exclure les fichiers inutiles
- Mettre les changements fréquents en bas du fichier
Multi-stage build (optimisé) :
# Stage 1 : Build
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
# Stage 2 : Runtime (plus léger)
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Docker Compose pour dev reproductible
Docker Compose orchestrate plusieurs services. Parfait pour :
- App Node.js + PostgreSQL + Redis
- Frontend + Backend + Database
- Stack complète en une commande
docker-compose.yml simple :
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/app
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=app
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Commandes :
docker-compose up -d # Lancer tous les services
docker-compose down # Arrêter et supprimer
docker-compose logs -f # Logs en temps réel
docker-compose exec db psql # Accéder au conteneur db
Volumes et networks
Volumes (persistance des données) :
# Bind mount (répertoire local)
docker run -v /chemin/local:/app myapp
# Nommé (géré par Docker)
docker run -v my_data:/data myapp
# En Compose
services:
db:
image: postgres
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Networks (communication inter-conteneurs) :
# Créer un network
docker network create my_network
# Connecter les conteneurs
docker run --network my_network --name app1 myapp
docker run --network my_network --name app2 myapp
# app1 peut pinger app2 par nom (DNS interne)
docker exec app1 ping app2
En Compose (automatique) :
services:
web:
build: .
db:
image: postgres
# web peut accéder db via http://db:5432
Workflow de développement
Setup complet pour 1 personne :
# 1. Clone repo
git clone myrepo
cd myrepo
# 2. Lancer l'env complet
docker-compose up
# 3. Code local = auto-sync dans le conteneur
docker-compose exec app npm install # Pour nouvelles dépendances
dockerfile.dev avec hot reload :
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
# Volume binding pour hot reload
COPY . .
CMD ["npm", "run", "dev"]
Pour équipes (2-10 devs) :
git pull
docker-compose pull # Nouvelles images
docker-compose up --build # Rebuild si changes
# Tout prêt. Zéro dépendances à installer.
Préparation pour la production
Docker Hub (publier l'image) :
docker tag my-app username/my-app:1.0
docker login
docker push username/my-app:1.0
Dockerfile optimisé pour prod :
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
# Security
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "server.js"]
Déployer sur serveur :
ssh server.com
# Pull l'image
docker pull username/my-app:1.0
# Lancer
docker run -d -p 80:3000 ---name app username/my-app:1.0
# Vérifier
docker logs -f app
Avec orchestration (Kubernetes) :
- Multi-réplicas automatiques
- Load balancing
- Auto-healing
- Rollouts/rollbacks
Bonnes pratiques
Checklist Docker :
- ✅ Images de base légères (alpine)
- ✅ Multi-stage builds
- ✅ Ne pas exécuter en root
- ✅ .dockerignore pour node_modules, .git
- ✅ Liveness/readiness probes
- ✅ Logs structurés (stdout, pas fichiers)
- ✅ Variables d'env pour config
- ❌ N'ajoutez pas de données sensibles
- ❌ Ne stockez pas des fichiers dans l'image
- ❌ N'oubliez pas le .dockerignore
Taille des images :
docker images
# Résultat :
node:18 1.5 GB (HEAVY)
node:18-alpine 0.2 GB (LEAN) ✓
Sécurité :
# Scanner les vulnérabilités
docker scan my-app:1.0
# Ajouter au CI/CD
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image my-app:1.0