spinny:~/writing $ less docker-containers-complete-guide.md
12Docker 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.34## Qu'est-ce que Docker ?56Docker 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.78```mermaid9graph TD10 subgraph "Traditional Deployment"11 A1[App 1] --> OS1[Guest OS]12 A2[App 2] --> OS2[Guest OS]13 OS1 --> HV[Hypervisor]14 OS2 --> HV15 HV --> HW1[Hardware]16 end1718 subgraph "Docker Deployment"19 B1[App 1] --> D1[Container]20 B2[App 2] --> D2[Container]21 D1 --> DE[Docker Engine]22 D2 --> DE23 DE --> HW2[Hardware]24 end25```2627### Conteneurs vs Machines Virtuelles2829| Aspect | Conteneurs | Machines Virtuelles |30|--------|-----------|---------------------|31| **Demarrage** | Secondes | Minutes |32| **Taille** | Mo | Go |33| **SE** | Partage le noyau hote | SE invite complet |34| **Isolation** | Niveau processus | Niveau materiel |35| **Performance** | Quasi native | Surcout de l'hyperviseur |36| **Densite** | Des centaines par hote | Des dizaines par hote |3738## Installer Docker3940```bash41# macOS42brew install --cask docker4344# Ubuntu/Debian45curl -fsSL https://get.docker.com | sh46sudo usermod -aG docker $USER4748# Verify installation49docker --version50docker run hello-world51```5253## Concepts Fondamentaux5455### Images5657Une 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.5859```bash60# Pull an image from Docker Hub61docker pull node:20-alpine6263# List local images64docker images6566# Remove an image67docker rmi node:20-alpine68```6970### Conteneurs7172Un conteneur est une instance en cours d'execution d'une image. Vous pouvez creer, demarrer, arreter et supprimer des conteneurs.7374```bash75# Run a container76docker run -d --name my-app -p 3000:3000 node:20-alpine7778# List running containers79docker ps8081# List all containers (including stopped)82docker ps -a8384# Stop a container85docker stop my-app8687# Remove a container88docker rm my-app8990# View logs91docker logs my-app9293# Execute a command inside a running container94docker exec -it my-app sh95```9697## Ecrire un Dockerfile9899Un Dockerfile est un fichier texte avec des instructions pour construire une image. Chaque instruction cree une couche.100101### Dockerfile Basique pour une App Node.js102103```dockerfile104# Use an official Node.js runtime as base image105FROM node:20-alpine106107# Set working directory108WORKDIR /app109110# Copy package files first (better caching)111COPY package.json package-lock.json ./112113# Install dependencies114RUN npm ci --only=production115116# Copy application code117COPY . .118119# Expose the port the app runs on120EXPOSE 3000121122# Command to run the application123CMD ["node", "server.js"]124```125126### Construire et Executer127128```bash129# Build the image130docker build -t my-node-app .131132# Run the container133docker run -d -p 3000:3000 my-node-app134135# Visit http://localhost:3000136```137138## Builds Multi-Stage139140Les builds multi-stage gardent vos images de production legeres en separant l'environnement de build de l'environnement d'execution.141142```dockerfile143# Stage 1: Build144FROM node:20-alpine AS builder145WORKDIR /app146COPY package.json package-lock.json ./147RUN npm ci148COPY . .149RUN npm run build150151# Stage 2: Production152FROM node:20-alpine AS runner153WORKDIR /app154COPY --from=builder /app/dist ./dist155COPY --from=builder /app/node_modules ./node_modules156COPY --from=builder /app/package.json ./157EXPOSE 3000158CMD ["node", "dist/server.js"]159```160161Cela 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.162163### Exemple Multi-Stage pour Next.js164165```dockerfile166FROM node:20-alpine AS deps167WORKDIR /app168COPY package.json package-lock.json ./169RUN npm ci170171FROM node:20-alpine AS builder172WORKDIR /app173COPY --from=deps /app/node_modules ./node_modules174COPY . .175RUN npm run build176177FROM node:20-alpine AS runner178WORKDIR /app179ENV NODE_ENV=production180COPY --from=builder /app/public ./public181COPY --from=builder /app/.next/standalone ./182COPY --from=builder /app/.next/static ./.next/static183EXPOSE 3000184CMD ["node", "server.js"]185```186187## Volumes : Donnees Persistantes188189Par defaut, les donnees a l'interieur d'un conteneur sont perdues lorsque le conteneur est supprime. Les volumes resolvent ce probleme.190191```bash192# Create a named volume193docker volume create my-data194195# Run with a volume196docker run -d -v my-data:/app/data my-app197198# Bind mount (map host directory to container)199docker run -d -v $(pwd)/data:/app/data my-app200201# List volumes202docker volume ls203```204205## Reseau206207Docker cree des reseaux isoles pour permettre aux conteneurs de communiquer.208209```bash210# Create a custom network211docker network create my-network212213# Run containers on the same network214docker run -d --name api --network my-network my-api215docker run -d --name db --network my-network postgres:16216217# Containers can reach each other by name218# From "api" container: postgres://db:5432219```220221```mermaid222graph LR223 subgraph "my-network"224 API[api container\nport 3000] -- "db:5432" --> DB[db container\nport 5432]225 end226 User -- "localhost:3000" --> API227```228229## Docker Compose230231Docker Compose vous permet de definir et d'executer des applications multi-conteneurs avec un seul fichier YAML.232233### docker-compose.yml234235```yaml236services:237 api:238 build: ./api239 ports:240 - "3000:3000"241 environment:242 - DATABASE_URL=postgres://user:pass@db:5432/mydb243 depends_on:244 - db245246 db:247 image: postgres:16-alpine248 environment:249 - POSTGRES_USER=user250 - POSTGRES_PASSWORD=pass251 - POSTGRES_DB=mydb252 volumes:253 - pgdata:/var/lib/postgresql/data254 ports:255 - "5432:5432"256257 redis:258 image: redis:7-alpine259 ports:260 - "6379:6379"261262volumes:263 pgdata:264```265266### Commandes267268```bash269# Start all services270docker compose up -d271272# View logs273docker compose logs -f274275# Stop all services276docker compose down277278# Rebuild and restart279docker compose up -d --build280281# Scale a service282docker compose up -d --scale api=3283```284285## .dockerignore286287Comme `.gitignore`, ce fichier empeche les fichiers inutiles d'etre copies dans l'image.288289```plaintext290node_modules291.git292.env293*.md294.next295dist296coverage297```298299## Bonnes Pratiques pour la Production300301### 1. Utilisez des Images de Base Legeres302303```dockerfile304# Bad: 1GB+305FROM node:20306307# Good: ~180MB308FROM node:20-alpine309```310311### 2. Ne pas executer en tant que Root312313```dockerfile314FROM node:20-alpine315RUN addgroup -S app && adduser -S app -G app316USER app317WORKDIR /home/app318COPY --chown=app:app . .319```320321### 3. Utilisez des Tags d'Image Specifiques322323```dockerfile324# Bad: can change unexpectedly325FROM node:latest326327# Good: pinned version328FROM node:20.11-alpine3.19329```330331### 4. Exploitez le Cache de Build332333Ordonnez les instructions de votre Dockerfile de la moins a la plus frequemment modifiee :334335```dockerfile336FROM node:20-alpine337WORKDIR /app338339# These change rarely - cached340COPY package.json package-lock.json ./341RUN npm ci --only=production342343# This changes often - not cached344COPY . .345```346347### 5. Health Checks348349```dockerfile350HEALTHCHECK --interval=30s --timeout=3s --retries=3 \351 CMD wget -qO- http://localhost:3000/health || exit 1352```353354### 6. Utilisez des Variables d'Environnement355356```dockerfile357ENV NODE_ENV=production358ENV PORT=3000359```360361## Aide-Memoire des Commandes Docker Courantes362363```bash364# Images365docker build -t name:tag . # Build image366docker images # List images367docker rmi image_name # Remove image368docker image prune # Remove unused images369370# Containers371docker run -d -p 3000:3000 image # Run detached372docker ps # List running373docker stop container_name # Stop374docker rm container_name # Remove375docker logs -f container_name # Follow logs376docker exec -it container sh # Shell into container377378# Compose379docker compose up -d # Start services380docker compose down # Stop services381docker compose logs -f # Follow all logs382docker compose ps # List services383384# Cleanup385docker system prune -a # Remove everything unused386```387388## De Docker a Kubernetes389390Docker 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 :3913921. **Docker** : construit et execute les conteneurs3932. **Kubernetes** : orchestre les conteneurs a grande echelle (planification, mise a l'echelle, auto-reparation)394395Si vous etes interesse par l'etape suivante, consultez mon article sur l'Introduction a Kubernetes.396397## Conclusion398399Docker 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.400401La meilleure facon d'apprendre Docker est de containeriser un projet sur lequel vous travaillez deja. Commencez des aujourd'hui.402
:Docker pour Debutants : De Votre Premiere Image au Deploiement en Productionlines 1-402 (END) — press q to close