Docker a change la facon dont nous construisons, distribuons et executons les logiciels. Au lieu de "ca marche sur ma machine", Docker garantit que votre application fonctionne de la meme maniere partout - sur votre ordinateur portable, sur la machine d'un collegue, en CI/CD et en production. Dans ce guide, nous allons partir de zero jusqu'au deploiement d'une vraie application.
Qu'est-ce que Docker ?
Docker est une plateforme qui empaquete votre application et toutes ses dependances dans une unite standardisee appelee conteneur. Un conteneur est un processus isole et leger qui partage le noyau du systeme d'exploitation hote mais possede son propre systeme de fichiers, reseau et espace de processus.
Conteneurs vs Machines Virtuelles
| Aspect | Conteneurs | Machines Virtuelles |
|---|---|---|
| Demarrage | Secondes | Minutes |
| Taille | Mo | Go |
| SE | Partage le noyau hote | SE invite complet |
| Isolation | Niveau processus | Niveau materiel |
| Performance | Quasi native | Surcout de l'hyperviseur |
| Densite | Des centaines par hote | Des dizaines par hote |
Installer Docker
# macOS brew install --cask docker # Ubuntu/Debian curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Verify installation docker --version docker run hello-world
Concepts Fondamentaux
Images
Une image est un modele en lecture seule avec des instructions pour creer un conteneur. Pensez-y comme un instantane de votre application et de son environnement.
# Pull an image from Docker Hub docker pull node:20-alpine # List local images docker images # Remove an image docker rmi node:20-alpine
Conteneurs
Un conteneur est une instance en cours d'execution d'une image. Vous pouvez creer, demarrer, arreter et supprimer des conteneurs.
# Run a container docker run -d --name my-app -p 3000:3000 node:20-alpine # List running containers docker ps # List all containers (including stopped) docker ps -a # Stop a container docker stop my-app # Remove a container docker rm my-app # View logs docker logs my-app # Execute a command inside a running container docker exec -it my-app sh
Ecrire un Dockerfile
Un Dockerfile est un fichier texte avec des instructions pour construire une image. Chaque instruction cree une couche.
Dockerfile Basique pour une App Node.js
# Use an official Node.js runtime as base image FROM node:20-alpine # Set working directory WORKDIR /app # Copy package files first (better caching) COPY package.json package-lock.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port the app runs on EXPOSE 3000 # Command to run the application CMD ["node", "server.js"]
Construire et Executer
# Build the image docker build -t my-node-app . # Run the container docker run -d -p 3000:3000 my-node-app # Visit http://localhost:3000
Builds Multi-Stage
Les builds multi-stage gardent vos images de production legeres en separant l'environnement de build de l'environnement d'execution.
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:20-alpine AS runner WORKDIR /app COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
Cela produit une image avec uniquement la sortie compilee et les dependances de production - pas de code source, pas de dependances de developpement, pas d'outils de build.
Exemple Multi-Stage pour Next.js
FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static EXPOSE 3000 CMD ["node", "server.js"]
Volumes : Donnees Persistantes
Par defaut, les donnees a l'interieur d'un conteneur sont perdues lorsque le conteneur est supprime. Les volumes resolvent ce probleme.
# Create a named volume docker volume create my-data # Run with a volume docker run -d -v my-data:/app/data my-app # Bind mount (map host directory to container) docker run -d -v $(pwd)/data:/app/data my-app # List volumes docker volume ls
Reseau
Docker cree des reseaux isoles pour permettre aux conteneurs de communiquer.
# Create a custom network docker network create my-network # Run containers on the same network docker run -d --name api --network my-network my-api docker run -d --name db --network my-network postgres:16 # Containers can reach each other by name # From "api" container: postgres://db:5432
Docker Compose
Docker Compose vous permet de definir et d'executer des applications multi-conteneurs avec un seul fichier YAML.
docker-compose.yml
services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb depends_on: - db db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: pgdata:
Commandes
# Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down # Rebuild and restart docker compose up -d --build # Scale a service docker compose up -d --scale api=3
.dockerignore
Comme .gitignore, ce fichier empeche les fichiers inutiles d'etre copies dans l'image.
node_modules .git .env *.md .next dist coverage
Bonnes Pratiques pour la Production
1. Utilisez des Images de Base Legeres
# Bad: 1GB+ FROM node:20 # Good: ~180MB FROM node:20-alpine
2. Ne pas executer en tant que Root
FROM node:20-alpine RUN addgroup -S app && adduser -S app -G app USER app WORKDIR /home/app COPY . .
3. Utilisez des Tags d'Image Specifiques
# Bad: can change unexpectedly FROM node:latest # Good: pinned version FROM node:20.11-alpine3.19
4. Exploitez le Cache de Build
Ordonnez les instructions de votre Dockerfile de la moins a la plus frequemment modifiee :
FROM node:20-alpine WORKDIR /app # These change rarely - cached COPY package.json package-lock.json ./ RUN npm ci --only=production # This changes often - not cached COPY . .
5. Health Checks
HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1
6. Utilisez des Variables d'Environnement
ENV NODE_ENV=production ENV PORT=3000
Aide-Memoire des Commandes Docker Courantes
# Images docker build -t name:tag . # Build image docker images # List images docker rmi image_name # Remove image docker image prune # Remove unused images # Containers docker run -d -p 3000:3000 image # Run detached docker ps # List running docker stop container_name # Stop docker rm container_name # Remove docker logs -f container_name # Follow logs docker exec -it container sh # Shell into container # Compose docker compose up -d # Start services docker compose down # Stop services docker compose logs -f # Follow all logs docker compose ps # List services # Cleanup docker system prune -a # Remove everything unused
De Docker a Kubernetes
Docker gere des conteneurs individuels. Lorsque vous devez orchestrer des centaines de conteneurs sur plusieurs serveurs, vous avez besoin de Kubernetes. Docker et Kubernetes sont complementaires :
- Docker : construit et execute les conteneurs
- Kubernetes : orchestre les conteneurs a grande echelle (planification, mise a l'echelle, auto-reparation)
Si vous etes interesse par l'etape suivante, consultez mon article sur l'Introduction a Kubernetes.
Conclusion
Docker est une competence fondamentale pour les developpeurs modernes. Il elimine les inconsistances d'environnement, simplifie le deploiement et constitue la base de l'orchestration de conteneurs avec Kubernetes. Commencez avec un simple Dockerfile, passez a Docker Compose pour les applications multi-services, et adoptez les builds multi-stage et les bonnes pratiques de securite au fur et a mesure que vous progressez.
La meilleure facon d'apprendre Docker est de containeriser un projet sur lequel vous travaillez deja. Commencez des aujourd'hui.