Docker pour les développeurs web : guide pratique

Pourquoi Docker change tout
"Ça marche sur ma machine." Combien de fois j'ai entendu (et dit) cette phrase. Sur un projet freelance, j'ai passé une journée entière à debugger un problème qui n'existait que sur le serveur de staging. La cause ? Une version différente de Node.js. Une journée perdue pour une variable d'environnement.
Docker élimine ce problème. L'environnement est identique partout : sur ma machine, sur celle du client, en production. Depuis que je l'utilise systématiquement, ce type de bug a disparu.
Les concepts essentiels
Image vs Conteneur
- Image : Template immuable (comme une classe)
- Conteneur : Instance en cours d'exécution (comme un objet)
# Télécharger une image
docker pull node:20-alpine
# Créer un conteneur à partir de l'image
docker run -it node:20-alpine sh
Dockerfile pour une app Next.js
Voici un Dockerfile optimisé pour la production :
# Étape 1: Dépendances
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
# Étape 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Étape 3: Production
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Créer un utilisateur non-root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
Pourquoi multi-stage ?
J'ai appris cette technique après avoir deployé une image de 1.2GB en production. Le déploiement prenait 10 minutes. Avec le multi-stage, la même app fait 150MB et se déploie en 30 secondes.
- Image finale plus légère (seulement le nécessaire)
- Meilleure sécurité (pas d'outils de build en production)
- Cache optimisé pour des builds plus rapides
Docker Compose pour le développement
Pour un environnement de développement complet :
# docker-compose.yml
version: "3.8"
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/myapp
depends_on:
- db
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Commandes utiles
# Démarrer tous les services
docker-compose up -d
# Voir les logs
docker-compose logs -f app
# Arrêter tout
docker-compose down
# Reconstruire après modification du Dockerfile
docker-compose up -d --build
.dockerignore
Aussi important que .gitignore :
node_modules
.next
.git
*.md
.env.local
.env*.local
npm-debug.log
Bonnes pratiques
1. Images légères
Utilisez les images Alpine quand c'est possible :
# ❌ ~1GB
FROM node:20
# ✅ ~150MB
FROM node:20-alpine
2. Utilisateur non-root
Ne jamais exécuter en tant que root en production :
RUN adduser -D appuser
USER appuser
3. Variables d'environnement
Séparez la configuration du code :
# Valeurs par défaut
ENV NODE_ENV=production
ENV PORT=3000
# Injection au runtime
docker run -e DATABASE_URL=... myapp
4. Health checks
Vérifiez que votre app fonctionne :
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1
Debugging
Quelques commandes essentielles :
# Entrer dans un conteneur en cours d'exécution
docker exec -it container_name sh
# Voir les processus
docker top container_name
# Inspecter un conteneur
docker inspect container_name
# Voir l'utilisation des ressources
docker stats
Conclusion
Docker a changé ma façon de travailler. Avant, configurer un environnement de dev prenait une demi-journée. Maintenant, docker-compose up et c'est parti. Quand un nouveau dev rejoint le projet, il est opérationnel en 5 minutes.
L'investissement initial pour apprendre Docker est vite rentabilisé. Et croyez-moi, vos ops vous remercieront.
Mon conseil : j'ai un repo GitHub avec mes templates Dockerfile + docker-compose pour Next.js, Node.js et Python. Je le clone à chaque nouveau projet. Créez le vôtre, vous gagnerez des heures.
Amor GABTNI
Développeur Full Stack & Mobile