🐳 Docker pour Data Engineers

Bienvenue dans ce module oĂč tu vas apprendre Ă  containeriser tes applications, lancer des services data en quelques secondes, et packager tes pipelines ETL de maniĂšre reproductible et portable — des compĂ©tences indispensables pour un Data Engineer moderne !


Prérequis

Niveau Compétence
✅ Requis Avoir suivi les modules 01_intro_data_engineering et 02_bash_for_data_engineers
✅ Requis Connaissances de base en Python
✅ Requis Avoir accùs à un terminal (Linux, Mac, ou Windows avec WSL)

Objectifs du module

À la fin de ce module, tu seras capable de :

  • Expliquer ce qu’est Docker et pourquoi il est essentiel en Data Engineering
  • Installer Docker sur Windows, macOS ou Linux
  • Lancer des services data (PostgreSQL, Kafka, Spark
) en une commande
  • Écrire un Dockerfile pour packager un script ETL
  • Utiliser les volumes, rĂ©seaux et docker-compose
  • DĂ©bugger des containers comme un pro
  • Appliquer les bonnes pratiques professionnelles

C’est quoi Docker ?

Docker est un outil qui permet d’exĂ©cuter des applications dans des environnements isolĂ©s, reproductibles et portables, appelĂ©s containers.

Au lieu d’installer une application (et toutes ses dĂ©pendances) directement sur ton systĂšme, tu la mets dans une “boĂźte” (le container) avec tout ce dont elle a besoin.

Docker ≠ Machine Virtuelle

Aspect Machine Virtuelle (VM) Container Docker
Contenu OS complet + kernel + drivers + apps App + libs + systĂšme minimal
Taille Plusieurs Go Quelques Mo Ă  centaines de Mo
Démarrage Minutes Secondes/millisecondes
Performance Overhead important Quasi-natif
Isolation ComplĂšte (hyperviseur) Au niveau processus

Analogies pour bien comprendre

Analogie Explication
🧳 La valise prĂȘte Un container = une valise dĂ©jĂ  remplie. Tu la prends, tu voyages, tu es opĂ©rationnel partout.
đŸ± Le tupperware Tu prĂ©pares un plat, tu le mets dans une boĂźte hermĂ©tique. Chez toi ou ailleurs : c’est le mĂȘme plat.
📩 Le zip complet Code + librairies + config dans un package. Mais avec la garantie que l’exĂ©cution est identique partout.

â„č Le savais-tu ?

Docker a été créé en 2013 par Solomon Hykes chez dotCloud (devenu Docker, Inc.).

Le nom vient des dockers (ouvriers portuaires) qui chargent et dĂ©chargent des containers sur les bateaux — exactement ce que fait Docker avec les applications !

📖 Histoire de Docker sur Wikipedia


1. Pourquoi Docker est indispensable pour un Data Engineer

En Data Engineering, tu dois souvent :

  • Manipuler des bases de donnĂ©es (PostgreSQL, MySQL, MongoDB
)
  • Lancer des brokers de messages (Kafka, RabbitMQ
)
  • DĂ©ployer des pipelines ETL
  • Faire tourner des jobs Spark ou des APIs

❌ Sans Docker

ProblÚme Conséquence
Installation manuelle complexe Heures perdues en config
Conflits de versions (Java, Python, drivers) “Ça marchait hier
”
Environnements diffĂ©rents (local ≠ prod) Bugs en production uniquement
Onboarding difficile Nouveaux = 2 jours pour installer

✅ Avec Docker

Avantage Exemple concret
PostgreSQL en 1 commande docker run postgres:16
Test Kafka + Spark sur laptop Stack complĂšte en local
ETL packagé et portable Tourne identique partout
Onboarding en 10 minutes docker-compose up et c’est parti

💡 En rĂ©sumĂ© : Docker est un outil central pour crĂ©er des environnements data reproductibles et industrialisables. Fini le 😅 “chez moi ça marche” !


2. Concepts clés Docker

Avant d’aller plus loin, maütrise ces 6 notions fondamentales :

Concept Description Analogie
Image ModÚle figé (blueprint) contenant OS + dépendances + code Une recette de cuisine
Container Instance en cours d’exĂ©cution d’une image Un plat prĂ©parĂ© Ă  partir de la recette
Registry Magasin d’images (Docker Hub, ECR, GHCR) Un catalogue de recettes en ligne
Volume Stockage persistant en dehors du container Un disque dur externe branché
Network Réseau virtuel entre containers Un réseau local privé
Build context Fichiers envoyés à Docker lors du build Le dossier de travail

Image Docker

Une image contient : - Un systùme de base (ex: python:3.11-slim) - Des bibliothùques (pandas, pyarrow, pyspark
) - Ton code (scripts, fichiers de config)

On ne modifie pas une image — on en reconstruit une nouvelle à partir d’un Dockerfile.

Container

Un container est une instance vivante d’une image : - Tu crĂ©es une image → tu la lances → tu obtiens un container - Tu peux dĂ©marrer, arrĂȘter, supprimer un container sans toucher Ă  l’image - Plusieurs containers peuvent tourner Ă  partir de la mĂȘme image

Registry

Un registry stocke et partage les images : - Docker Hub (public/privĂ©) — le plus connu - GitHub Container Registry (GHCR) - AWS ECR, GCP Artifact Registry, Azure ACR

Volume

Les donnĂ©es ne doivent pas “mourir” avec le container : - Sans volume : container supprimĂ© = donnĂ©es perdues - Avec volume : donnĂ©es persistantes, partageables

Network

Permet aux containers de communiquer entre eux : - Ex: container etl se connecte à container postgres - Isolation du réseau de la machine hÎte

Build context

Quand tu fais docker build -t mon-image . : - Le . = tout ce que Docker envoie au daemon - Dossier de 10 Go = envoi de 10 Go - D’oĂč l’importance du .dockerignore !

Schéma visuel : Architecture Docker

┌─────────────────────────────────────────────────────────────┐
│                      DOCKER HOST                            │
│               (Laptop / Server / Cloud)                     │
├──────────────────────────────────────────────────────────────
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                  DOCKER ENGINE                      │    │
│  │                                                     │    │
│  │   ┌──────────┐  ┌──────────┐  ┌──────────┐          │    │
│  │   │  IMAGE   │  │  IMAGE   │  │  IMAGE   │          │    │ 
│  │   │ postgres │  │  python  │  │  spark   │          │    │
│  │   └────┬─────┘  └────┬─────┘  └────┬─────┘          │    │
│  │        │             │             │                │    │
│  │        â–Œ             â–Œ             â–Œ                │    │
│  │   ┌──────────┐  ┌──────────┐  ┌──────────┐          │    │
│  │   │CONTAINER │  │CONTAINER │  │CONTAINER │          │    │
│  │   │ de-postgres│ │  de-etl  │  │ de-spark │         │    │
│  │   └────┬─────┘  └──────────┘  └──────────┘          │    │
│  │        │                                            │    │
│  │        â–Œ                                            │    │
│  │   ┌──────────┐       ┌──────────────┐               │    │
│  │   │  VOLUME  │       │   NETWORK    │               │    │
│  │   │ pg_data  │       │  de-network  │               │    │
│  │   └──────────┘       └──────────────┘               │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3. Installation de Docker

SystĂšme Comment installer
đŸȘŸ Windows Docker Desktop + WSL2
🍎 macOS Docker Desktop (Intel ou Apple Silicon)
🐧 Linux Docker Engine (apt/yum)

đŸȘŸ Windows (Docker Desktop + WSL2)

1. Activer WSL2 :

# Dans PowerShell en administrateur
wsl --install

2. TĂ©lĂ©charger Docker Desktop : - 🔗 https://www.docker.com/products/docker-desktop/

3. Installer et redémarrer

4. Tester :

docker --version
docker run --rm hello-world

🍎 macOS (Intel & Apple Silicon)

1. TĂ©lĂ©charger Docker Desktop : - 🔗 https://www.docker.com/products/docker-desktop/ - Choisir la version Intel ou Apple Silicon (M1/M2/M3)

2. Glisser l’app dans Applications

3. Lancer Docker Desktop (icîne 🐳 dans la barre)

4. Tester :

docker --version
docker run --rm hello-world

🐧 Linux (Ubuntu/Debian)

# 1. Mettre à jour et installer les prérequis
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release

# 2. Ajouter la clé GPG officielle
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 3. Ajouter le dépÎt Docker
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 4. Installer Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 5. Tester
sudo docker run --rm hello-world

# 6. (Optionnel) Utiliser Docker sans sudo
sudo usermod -aG docker $USER
# Puis déconnexion/reconnexion

Vérifier ton installation

Voir le code
%%bash
# Vérifier la version de Docker
docker --version

# Vérifier que Docker fonctionne
docker run --rm hello-world

4. Commandes Docker essentielles

Voici ton cheat sheet de base :

Lancer un container

docker run image                    # Lancer un container
docker run -d image                 # En arriĂšre-plan (detached)
docker run -it image bash           # Mode interactif
docker run --rm image               # Supprime le container Ă  la fin
docker run --name mon-container image  # Nommer le container

Lister

docker ps                           # Containers en cours
docker ps -a                        # Tous les containers (y compris stoppés)
docker images                       # Lister les images locales

Stopper / Supprimer

docker stop CONTAINER_ID            # ArrĂȘter un container
docker rm CONTAINER_ID              # Supprimer un container
docker rmi IMAGE_ID                 # Supprimer une image

Télécharger une image

docker pull postgres:16             # Télécharger depuis Docker Hub

Logs

docker logs CONTAINER_ID            # Voir les logs
docker logs -f CONTAINER_ID         # Suivre les logs en temps réel

Raccourcis utiles

Commande Description
docker ps -a Voir tous les containers
docker logs -f Suivre les logs en live
docker exec -it <container> bash Entrer dans un container
docker system prune Nettoyer les ressources inutilisées
Voir le code
%%bash
# Lister les images disponibles localement
echo "=== Images locales ==="
docker images

echo ""
echo "=== Containers en cours ==="
docker ps

echo ""
echo "=== Tous les containers ==="
docker ps -a

5. Docker pour lancer des services Data

Docker est extrĂȘmement pratique pour tester rapidement des services utilisĂ©s en Data Engineering.

PostgreSQL (exemple détaillé)

docker run -d \
  --name demo-postgres \
  -e POSTGRES_USER=de_user \
  -e POSTGRES_PASSWORD=de_pass \
  -e POSTGRES_DB=de_db \
  -p 5432:5432 \
  postgres:16

Connexion : - Host: localhost - Port: 5432 - User: de_user - Password: de_pass - Database: de_db

Tu peux ensuite te connecter avec DBeaver, psql, Python (psycopg2), etc.


Autres services (one-liners)

Service Commande
Redis docker run -d --name demo-redis -p 6379:6379 redis:latest
MongoDB docker run -d --name demo-mongo -p 27017:27017 mongo:latest
Kafka docker run -d --name demo-kafka -p 9092:9092 bitnami/kafka:latest
Spark docker run -it --name demo-spark bitnami/spark:latest pyspark
Airflow docker pull apache/airflow:latest
Jupyter docker run -p 8888:8888 jupyter/scipy-notebook

💡 Astuce : Pour Kafka et Airflow, prĂ©fĂšre docker-compose car ils nĂ©cessitent plusieurs services (Zookeeper, webserver, scheduler
), on le verra un peu plus en bas.

Voir le code
%%bash
# Lancer PostgreSQL (si Docker est installé)
docker run -d \
  --name demo-postgres \
  -e POSTGRES_USER=de_user \
  -e POSTGRES_PASSWORD=de_pass \
  -e POSTGRES_DB=de_db \
  -p 5432:5432 \
  postgres:16

echo "PostgreSQL lancé sur localhost:5432"

# Vérifier qu'il tourne
docker ps --filter name=demo-postgres
Voir le code
%%bash
# Nettoyage : stopper et supprimer le container
docker stop demo-postgres 2>/dev/null
docker rm demo-postgres 2>/dev/null
echo "đŸ§č Container demo-postgres supprimĂ©"

6. Dockerfile : créer son image

Le Dockerfile est un fichier texte qui décrit comment construire une image.

Instructions principales

Instruction RĂŽle Exemple
FROM Image de base FROM python:3.11-slim
WORKDIR Répertoire de travail WORKDIR /app
COPY Copier des fichiers COPY etl.py .
RUN Exécuter une commande (build) RUN pip install pandas
CMD Commande par défaut (run) CMD ["python", "etl.py"]
ENTRYPOINT Point d’entrĂ©e fixe ENTRYPOINT ["python"]
ENV Variable d’environnement ENV PYTHONUNBUFFERED=1
EXPOSE Port exposé (documentation) EXPOSE 8000

Structure de projet recommandée

etl_project/
├── Dockerfile
├── .dockerignore
├── requirements.txt
├── src/
│   ├── etl.py
│   └── utils.py
└── data/               # ⚠ Ne pas inclure dans l'image !
    └── input.csv

💡 Important : Le Dockerfile doit ĂȘtre Ă  la racine du service que tu veux packager.

Exemple : Dockerfile pour un ETL Python

# 1. Image de base légÚre
FROM python:3.11-slim

# 2. Variables d'environnement
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

# 3. Répertoire de travail
WORKDIR /app

# 4. Copier et installer les dépendances (cache Docker)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 5. Copier le code
COPY src/ ./src/

# 6. Commande par défaut
CMD ["python", "src/etl.py"]

Construire l’image

cd etl_project
docker build -t etl-image:1.0 .

Lancer le container

docker run --rm etl-image:1.0

7. Le fichier .dockerignore

Le .dockerignore empĂȘche d’envoyer des fichiers inutiles dans le build context.

❌ Sans .dockerignore

  • Images Ă©normes (datasets inclus)
  • Builds lents (envoi de Go de donnĂ©es)
  • Fuites de secrets (.env, clĂ©s SSH)

✅ Exemple de .dockerignore (Data Engineer)

# Données
data/
*.csv
*.parquet
*.json

# Python
__pycache__/
*.pyc
*.pyo
venv/
.venv/
*.egg-info/

# Secrets
.env
*.key
*.pem
secrets/

# Notebooks
*.ipynb
.ipynb_checkpoints/

# Git
.git/
.gitignore

# IDE
.idea/
.vscode/
*.swp

# Logs
logs/
*.log

# OS
.DS_Store
Thumbs.db

# Docker
Dockerfile
docker-compose*.yml

💡 Rùgle d’or : le .dockerignore est aussi important que le Dockerfile !


8. Multi-stage builds

Les multi-stage builds permettent de créer des images plus légÚres en séparant :

  1. Stage build : compilation, installation des dépendances lourdes
  2. Stage runtime : uniquement ce qui est nécessaire pour exécuter

Pourquoi c’est utile ?

Sans multi-stage Avec multi-stage
Image de 1.5 Go Image de 200 Mo
Outils de build inclus Seulement le runtime
Surface d’attaque large SĂ©curitĂ© renforcĂ©e

Exemple : ETL Python avec multi-stage

# ============== STAGE 1 : BUILD ==============
FROM python:3.11-slim AS builder

WORKDIR /app

# Installer les dépendances dans un dossier isolé
COPY requirements.txt .
RUN pip install --prefix=/install --no-cache-dir -r requirements.txt

# ============== STAGE 2 : RUNTIME ==============
FROM python:3.11-slim AS runtime

WORKDIR /app

# Copier seulement les dépendances installées
COPY --from=builder /install /usr/local

# Copier le code
COPY src/ ./src/

# Variables d'environnement
ENV PYTHONUNBUFFERED=1

CMD ["python", "src/etl.py"]

RĂ©sultat : image finale lĂ©gĂšre et sĂ©curisĂ©e ! 🎉


9. Volumes & Networks

9.1 Volumes : persister les données

Les volumes permettent de stocker des données en dehors des containers.

Types de volumes :

Type Syntaxe Usage
Bind mount -v /host/path:/container/path Données locales (dev)
Volume nommé -v myvolume:/container/path Données persistantes (prod)

Exemple : monter un dossier local

docker run -d \
  --name etl-with-data \
  -v $(pwd)/data:/app/data \
  etl-image:1.0
  • $(pwd)/data → dossier sur ta machine
  • /app/data → dossier dans le container
  • Tu supprimes le container → les donnĂ©es restent dans ./data

9.2 Networks : faire communiquer les containers

Par défaut, Docker crée un réseau bridge. Tu peux créer un réseau dédié :

# Créer un réseau
docker network create de-network

# Lancer des containers sur ce réseau
docker run -d --name de-postgres --network de-network postgres:16
docker run -d --name de-etl --network de-network etl-image:1.0

Avantage : dans le code Python, tu te connectes Ă  de-postgres (nom du container) au lieu de localhost !

# Dans etl.py
conn = psycopg2.connect(
    host="de-postgres",  # Nom du container !
    database="de_db",
    user="de_user",
    password="de_pass"
)

10. Docker Compose

Quand tu as plusieurs services (Postgres + ETL + API
), tu ne veux pas tout lancer à la main.

docker-compose.yml permet de décrire une stack complÚte et de la lancer avec une seule commande.

Structure projet avec docker-compose

de-pipeline/
├── docker-compose.yml      # À la racine !
├── etl/
│   ├── Dockerfile
│   ├── requirements.txt
│   └── etl.py
└── data/
    └── input.csv

Exemple : PostgreSQL + ETL

version: "3.9"

services:
  postgres:
    image: postgres:16
    container_name: de-postgres
    environment:
      POSTGRES_USER: de_user
      POSTGRES_PASSWORD: de_pass
      POSTGRES_DB: de_db
    ports:
      - "5432:5432"
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U de_user -d de_db"]
      interval: 5s
      timeout: 5s
      retries: 5

  etl:
    build: ./etl
    container_name: de-etl
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DB_HOST: postgres
      DB_USER: de_user
      DB_PASSWORD: de_pass
      DB_NAME: de_db
    volumes:
      - ./data:/app/data

volumes:
  pg_data:

Commandes docker-compose

# Lancer la stack
docker compose up -d

# Voir les logs
docker compose logs -f

# Stopper la stack
docker compose down

# Stopper et supprimer les volumes
docker compose down -v

# Reconstruire les images
docker compose up --build

11. Debug Docker

En Data Engineering, tu devras souvent débugger un job qui tourne dans un container.

Voir les logs

docker logs de-etl                  # Voir les logs
docker logs -f de-etl               # Suivre en temps réel
docker logs --tail 100 de-etl       # Les 100 derniĂšres lignes

Entrer dans un container

docker exec -it de-etl bash         # Ouvrir un shell bash
docker exec -it de-etl sh           # Pour images Alpine

Cas d’usage : - Inspecter les fichiers (ls, cat) - Tester une connexion DB (psql, ping) - VĂ©rifier les variables d’environnement (env) - Lancer un script manuellement (python etl.py)

Inspecter un container

docker inspect de-etl               # Détails complets (JSON)
docker inspect --format='{{.NetworkSettings.IPAddress}}' de-etl  # IP du container

Cas Data Engineering typiques

ProblĂšme Solution
ETL qui plante sans message docker logs de-etl
Connexion DB refusée docker exec -it de-etl bash puis ping postgres
Spark ne voit pas Kafka Vérifier les networks Docker
Fichier introuvable docker exec -it de-etl ls /app/data
Variable d’env manquante docker exec -it de-etl env

12. Erreurs fréquentes & Bonnes pratiques

❌ Erreurs frĂ©quentes

Erreur Conséquence Solution
Pas de .dockerignore Images de plusieurs Go Créer un .dockerignore complet
Tout en latest Comportement non reproductible Tags versionnés (image:1.0.0)
Dockerfile mal placé Build context gigantesque Dockerfile à la racine du service
Secrets dans l’image Fuite de credentials Variables d’env ou secrets manager
Pas de nettoyage Disque saturé docker system prune réguliÚrement
DonnĂ©es dans l’image Image Ă©norme, non portable Utiliser des volumes
Versions non fixées Builds cassés aprÚs mise à jour Fixer les versions dans requirements.txt

✅ Bonnes pratiques

Pratique Pourquoi
Images slim python:3.11-slim = plus léger et rapide
Multi-stage builds Images finales légÚres
Tags versionnés etl:1.0.0, etl:prod, etl:staging
.dockerignore Builds rapides et sécurisés
Healthchecks Savoir si un service est prĂȘt
Volumes pour les données Persistance et portabilité
Nettoyage régulier docker system prune

đŸ§č Commandes de nettoyage

# Supprimer les containers arrĂȘtĂ©s
docker container prune

# Supprimer les images non utilisées
docker image prune

# Tout nettoyer (⚠ attention en prod !)
docker system prune -a

Quiz de fin de module

Réponds aux questions suivantes pour vérifier tes acquis.


❓ Q1. Quelle est la diffĂ©rence entre une image et un container Docker ?

  1. Une image est un container en cours d’exĂ©cution
  2. Un container est une instance en cours d’exĂ©cution d’une image
  3. C’est la mĂȘme chose
  4. Une image contient plusieurs containers
💡 Voir la rĂ©ponse

✅ RĂ©ponse : b — Une image est un modĂšle figĂ©, un container est son exĂ©cution vivante.


❓ Q2. Pourquoi le fichier .dockerignore est-il important ?

  1. Pour ignorer les erreurs Docker
  2. Pour réduire la taille du build context et sécuriser les builds
  3. Pour ignorer les logs
  4. C’est optionnel et inutile
💡 Voir la rĂ©ponse

✅ RĂ©ponse : b — Il Ă©vite d’envoyer des fichiers inutiles (donnĂ©es, secrets) dans le build context.


❓ Q3. Quelle commande permet d’entrer dans un container en cours d’exĂ©cution ?

  1. docker run -it container bash
  2. docker exec -it container bash
  3. docker enter container
  4. docker ssh container
💡 Voir la rĂ©ponse

✅ RĂ©ponse : b — docker exec -it <container> bash ouvre un shell interactif.


❓ Q4. À quoi servent les multi-stage builds ?

  1. À lancer plusieurs containers en parallùle
  2. À crĂ©er des images plus lĂ©gĂšres en sĂ©parant build et runtime
  3. À versionner les images
  4. À gĂ©rer les rĂ©seaux Docker
💡 Voir la rĂ©ponse

✅ RĂ©ponse : b — Multi-stage = image finale lĂ©gĂšre avec seulement le runtime nĂ©cessaire.


❓ Q5. OĂč doit-on placer le fichier docker-compose.yml ?

  1. Dans le dossier /etc/docker/
  2. À la racine du projet multi-services
  3. Dans chaque sous-dossier de service
  4. N’importe oĂč
💡 Voir la rĂ©ponse

✅ RĂ©ponse : b — Le docker-compose.yml est Ă  la racine du projet, avec les services dans des sous-dossiers.


❓ Q6. Quelle commande permet de voir les logs d’un container en temps rĂ©el ?

  1. docker logs container
  2. docker logs -f container
  3. docker watch container
  4. docker tail container
💡 Voir la rĂ©ponse

✅ RĂ©ponse : b — L’option -f (follow) suit les logs en temps rĂ©el.


Mini-projet : ETL Dockerisé complet

Objectif

Créer un pipeline ETL Dockerisé qui lit un CSV, transforme les données, et les charge dans PostgreSQL.

Contexte

Tu dois packager un job ETL Python avec Docker et le faire communiquer avec une base PostgreSQL, le tout orchestré par docker-compose.

Contraintes

  1. Créer la structure de projet suivante :
de-mini-projet/
├── docker-compose.yml
├── etl/
│   ├── Dockerfile
│   ├── .dockerignore
│   ├── requirements.txt
│   └── etl.py
└── data/
    └── sales.csv
  1. L’ETL doit :

    • Lire data/sales.csv
    • Calculer une colonne total = quantity * price
    • InsĂ©rer les donnĂ©es dans PostgreSQL
  2. Utiliser un healthcheck pour attendre que Postgres soit prĂȘt

  3. Les donnĂ©es doivent ĂȘtre montĂ©es via un volume

✅ Solution du mini-projet

đŸ“„ Afficher la solution complĂšte

1. data/sales.csv

date,product,quantity,price
2024-01-01,Laptop,5,999.99
2024-01-02,Mouse,20,29.99
2024-01-03,Keyboard,15,79.99
2024-01-04,Monitor,8,299.99
2024-01-05,Laptop,3,999.99

2. etl/requirements.txt

pandas==2.1.4
psycopg2-binary==2.9.9
sqlalchemy==2.0.25

3. etl/.dockerignore

__pycache__/
*.pyc
.env
*.log

4. etl/Dockerfile

FROM python:3.11-slim

ENV PYTHONUNBUFFERED=1

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY etl.py .

CMD ["python", "etl.py"]

5. etl/etl.py

import os
import pandas as pd
from sqlalchemy import create_engine

def main():
    # Configuration depuis variables d'environnement
    db_host = os.environ.get('DB_HOST', 'localhost')
    db_user = os.environ.get('DB_USER', 'de_user')
    db_pass = os.environ.get('DB_PASSWORD', 'de_pass')
    db_name = os.environ.get('DB_NAME', 'de_db')
    
    print("🚀 DĂ©marrage de l'ETL...")
    
    # Extract
    print("đŸ“„ Lecture du fichier CSV...")
    df = pd.read_csv('/app/data/sales.csv')
    print(f"   {len(df)} lignes lues")
    
    # Transform
    print("🔄 Transformation des donnĂ©es...")
    df['total'] = df['quantity'] * df['price']
    df['loaded_at'] = pd.Timestamp.now()
    
    # Load
    print("đŸ“€ Chargement dans PostgreSQL...")
    engine = create_engine(f'postgresql://{db_user}:{db_pass}@{db_host}/{db_name}')
    df.to_sql('sales', engine, if_exists='replace', index=False)
    
    print("✅ ETL terminĂ© avec succĂšs !")
    print(df.head())

if __name__ == "__main__":
    main()

6. docker-compose.yml

version: "3.9"

services:
  postgres:
    image: postgres:16
    container_name: de-postgres
    environment:
      POSTGRES_USER: de_user
      POSTGRES_PASSWORD: de_pass
      POSTGRES_DB: de_db
    ports:
      - "5432:5432"
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U de_user -d de_db"]
      interval: 5s
      timeout: 5s
      retries: 5

  etl:
    build: ./etl
    container_name: de-etl
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DB_HOST: postgres
      DB_USER: de_user
      DB_PASSWORD: de_pass
      DB_NAME: de_db
    volumes:
      - ./data:/app/data

volumes:
  pg_data:

7. Lancer le projet :

cd de-mini-projet
docker compose up --build

8. Vérifier les données dans Postgres :

docker exec -it de-postgres psql -U de_user -d de_db -c "SELECT * FROM sales;"

📚 Ressources pour aller plus loin

🌐 Documentation officielle

🎼 Pratique

📩 Images utiles pour Data Engineering


âžĄïž Prochaine Ă©tape

Maintenant que tu maĂźtrises Docker, passons Ă  l’orchestration de containers Ă  grande Ă©chelle !

👉 Module suivant : 15_kubernetes_fundamentals — Orchestrer des containers avec Kubernetes

Tu vas apprendre : - Pods, Deployments, Services - ConfigMaps, Secrets - Spark et Airflow sur Kubernetes


🎉 FĂ©licitations ! Tu as terminĂ© le module Docker pour Data Engineers.

Retour au sommet