AccueilBlogTest technique Docker et Docker Compose pour la data : stacks locales
Guide recrutement data

Test technique Docker et Docker Compose pour la data : stacks locales

Docker est le pre-requis pour tout Data Engineer moderne. En entretien, on va au-dela du simple docker run — on evalue la capacite a architecturer des stacks locales et des images optimisees.

Data Builder·Juin 2025·6 min de lecture·Data Engineer
Sommaire
  1. Dockerfile optimise pour la data
  2. Docker Compose : stack data locale
  3. Networking et volumes
  4. Multi-stage builds
  5. Image registry et CI
  6. Docker vers Kubernetes
  7. Grille

1Dockerfile optimise pour un projet data

Question discriminante

Quelles sont les bonnes pratiques pour un Dockerfile Python data ?

# Multi-stage build : image finale legere FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . # --no-cache-dir : reduit la taille de l image RUN pip install --no-cache-dir --user -r requirements.txt # Image finale : ne pas copier pip, seulement les packages installes FROM python:3.11-slim WORKDIR /app # Copier seulement les packages installes COPY --from=builder /root/.local /root/.local COPY . . # Pas de root en production RUN useradd -m appuser USER appuser # Variables d environnement ENV PATH=/root/.local/bin:$PATH ENV PYTHONUNBUFFERED=1 CMD ['python', 'main.py']
  • slim — image de base minimale. Eviter :latest, toujours specifier la version
  • Layer caching — copier requirements.txt AVANT le code source pour maximiser le cache
  • Non-root user — bonne pratique de securite
  • PYTHONUNBUFFERED=1 — logs visibles en temps reel

2Docker Compose : stack data locale complete

Question discriminante

Comment monteriez-vous une stack data locale avec Airflow, PostgreSQL et dbt ?

version: '3.8' services: postgres: image: postgres:15 environment: POSTGRES_DB: datadb POSTGRES_USER: data POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql ports: - '5432:5432' healthcheck: test: ['CMD', 'pg_isready', '-U', 'data'] interval: 10s airflow: image: apache/airflow:2.9.0 depends_on: postgres: condition: service_healthy environment: AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://data:${POSTGRES_PASSWORD}@postgres/airflow volumes: - ./dags:/opt/airflow/dags - ./logs:/opt/airflow/logs ports: - '8080:8080' dbt: build: ./dbt depends_on: [postgres] volumes: - ./dbt:/dbt command: ['dbt', 'run'] volumes: postgres_data:

3Networking : comment les services communiquent

Question discriminante

Comment un service Airflow appelle-t-il un service PostgreSQL dans Docker Compose ?

  • DNS interne — dans Docker Compose, chaque service est accessible via son nom de service. Ex : postgres:5432 depuis airflow
  • Ports exposes — ports: expose sur la machine hote. Pas necessaire pour la communication inter-services
  • healthcheck + depends_on — attendre que le service soit vraiment pret avant de demarrer les dependances
  • Networks — isoler des groupes de services. Par defaut, tous les services d un Compose sont sur le meme reseau

4Multi-stage builds : optimiser la taille

Question discriminante

Pourquoi utilise-t-on les multi-stage builds ? Quelle reduction de taille obtient-on typiquement ?

  • Probleme — les outils de build (gcc, pip, headers) ne sont pas necessaires en production mais augmentent la taille de l image
  • Solution — builder dans une image complete, copier seulement les artefacts finaux dans une image slim
  • Gains typiques — image Python avec numpy/pandas : 800MB → 200MB avec multi-stage
  • Layer caching — les layers sont mis en cache. Copier requirements.txt avant le code pour que le rebuild soit rapide

5Registry et CI/CD des images

Question discriminante

Comment organisez-vous la gestion des images Docker dans un projet data d equipe ?

  • Registry — Google Artifact Registry, AWS ECR, Docker Hub (public). Jamais pousser directement en latest sans tag
  • Tagging — tag avec le SHA du commit (image:sha-abc123) pour la tracabilite
  • Build en CI — GitHub Actions ou Cloud Build construit et pousse l image automatiquement
  • .dockerignore — exclure .git, __pycache__, .env, les fichiers de donnees. Reduit le contexte de build

6De Docker Compose vers Kubernetes

  • docker-compose.yml → Kubernetes manifests — un service Compose = un Deployment + Service K8s
  • kompose convert — outil officiel pour convertir un docker-compose.yml en manifests K8s
  • Docker Compose pour le dev local — K8s pour la production. Ne pas essayer de faire du K8s en local pour le dev quotidien
  • Tilt / Skaffold — workflows de developpement local qui synchronisent le code avec un cluster K8s
# docker-compose.yml stack data locale complète version: '3.8' services: postgres: image: postgres:16 environment: POSTGRES_DB: databuilder POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s kafka: image: confluentinc/cp-kafka:7.5.0 depends_on: [zookeeper] environment: KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" airflow: image: apache/airflow:2.8.0 depends_on: postgres: {condition: service_healthy} environment: AIRFLOW__CORE__SQL_ALCHEMY_CONN: postgresql+psycopg2://postgres:${POSTGRES_PASSWORD}@postgres/airflow AIRFLOW__CORE__EXECUTOR: LocalExecutor volumes: - ./dags:/opt/airflow/dags command: ["airflow", "standalone"] dbt: build: ./dbt volumes: - ./dbt:/dbt depends_on: [postgres] command: ["dbt", "run", "--profiles-dir", "/dbt"] volumes: postgres_data:
  • Healthchecks — toujours définir des healthchecks sur les services stateful (Postgres, Kafka, Redis). Les depends_on sans condition vérifient seulement que le container démarre, pas qu'il est prêt
  • Volumes nommés vs bind mounts — volumes nommés pour les données persistantes (Postgres data). Bind mounts pour le code source (./dags:/opt/airflow/dags) afin de développer sans rebuild
  • .env files — stocker les secrets dans .env (jamais dans docker-compose.yml). Ajouter .env au .gitignore. Fournir un .env.example avec des valeurs factices
  • Docker Compose profiles--profile monitoring pour démarrer Prometheus + Grafana uniquement en dev. Évite de surcharger l'environnement de base
  • Multi-stage builds — pour les images Python avec dependencies lourdes (PyTorch, Spark) : build stage installe les dépendances, runtime stage copie uniquement le nécessaire. Réduit la taille de l'image
  • Healthchecks obligatoires - definir des healthchecks sur les services stateful (Postgres, Kafka, Redis). Les depends_on sans condition verifient seulement que le container demarre
  • Volumes nommes vs bind mounts - volumes nommes pour les donnees persistantes (Postgres data). Bind mounts pour le code source (./dags:/opt/airflow/dags)
  • .env files - stocker les secrets dans .env (jamais dans docker-compose.yml). Ajouter .env au .gitignore. Fournir un .env.example avec des valeurs factices
  • Docker Compose profiles - --profile monitoring pour demarrer Prometheus + Grafana uniquement en dev. Evite de surcharger l environnement de base
  • Multi-stage builds - build stage installe les dependances, runtime stage copie uniquement le necessaire. Reduit la taille de l image de 3GB a 500MB

7Grille par niveau

NiveauMaitriseSignal GONO-GO
JuniorDockerfile basique, docker run, docker-compose upSait ecrire un Dockerfile Python, lance une stack avec ComposeNe sait pas ce qu est un volume
ConfirmeMulti-stage, healthchecks, networking Compose, .dockerignoreUtilise multi-stage, configure les healthchecks, sait pourquoi postgres:5432 marche entre servicesUtilise :latest partout, ne connait pas les multi-stage builds
SeniorRegistry CI/CD, securite (non-root, secrets), migration K8sA configure le push automatique en CI, utilise des users non-root, connait komposePousse des images avec des credentials en dur dans le Dockerfile

Vous recrutez un Data Engineer ?

Premier entretien gratuit. Rapport GO/NO-GO sous 48h.