🔝 Retour au Sommaire
Vous est-il déjà arrivé d'entendre : "Ça marche sur ma machine !" ? C'est l'une des phrases les plus frustrantes du développement logiciel. Un développeur a un projet qui fonctionne parfaitement sur son ordinateur, mais quand un collègue essaie de l'exécuter, c'est la catastrophe : erreurs de dépendances, versions incompatibles, configurations manquantes...
Docker peut transformer votre environnement de développement pour résoudre ces problèmes une fois pour toutes.
Jour 1 : Un nouveau développeur rejoint l'équipe
1. Cloner le dépôt Git ✅
2. Installer Python 3.9 (mais il a Python 3.11) 😰
3. Installer PostgreSQL (quelle version déjà ?) 😰
4. Installer Redis 😰
5. Configurer les variables d'environnement 😰
6. Installer les dépendances npm (erreurs de compilation) 😰
7. Lancer l'application... ça ne marche pas 😭
8. Déboguer pendant des heures 😭😭
9. Enfin ça fonctionne ! 🎉
10. Total : 1 journée perdue
Jour 1 : Un nouveau développeur rejoint l'équipe
1. Cloner le dépôt Git ✅
2. Ouvrir dans VS Code
3. Cliquer sur "Reopen in Container"
4. Attendre 2 minutes
5. Commencer à coder ✅
Total : 5 minutes
Un environnement de développement conteneurisé signifie que tout ce dont vous avez besoin pour développer (langages, outils, dépendances, bases de données) tourne dans un ou plusieurs conteneurs Docker.
✅ Environnement identique pour tous : Tous les développeurs ont exactement le même setup
✅ Onboarding rapide : Un nouveau développeur est opérationnel en minutes
✅ Isolation : Chaque projet a son propre environnement sans conflits
✅ Reproductibilité : "Ça marche sur ma machine" devient "Ça marche partout"
✅ Nettoyage facile : Supprimer le conteneur = environnement propre
✅ Pas de pollution : Votre machine reste propre
Projet A : Application Python 3.9 + PostgreSQL 13
Projet B : Application Python 3.11 + MongoDB
Projet C : Application Node.js 18 + Redis
Sans Docker : Installation et gestion de tous ces outils en local, risques de conflits.
Avec Docker : Chaque projet dans son conteneur, isolation totale.
VS Code Dev Containers est une extension de Visual Studio Code qui permet de développer à l'intérieur d'un conteneur Docker comme si vous développiez localement.
- Vous ouvrez un projet dans VS Code
- VS Code détecte la configuration Dev Container
- VS Code construit et démarre le conteneur
- VS Code connecte votre éditeur au conteneur
- Vous développez normalement, mais tout s'exécute dans le conteneur
Schéma simplifié :
Votre Machine
├─ VS Code (interface)
│ ↕️ (connexion)
└─ Docker
└─ Conteneur de développement
├─ Code source (volume monté)
├─ Outils de développement
├─ Extensions VS Code
└─ Terminal
Prérequis :
- Docker installé et en cours d'exécution
- Visual Studio Code installé
Installation de l'extension :
- Ouvrir VS Code
- Aller dans Extensions (Ctrl+Shift+X / Cmd+Shift+X)
- Rechercher "Dev Containers"
- Installer l'extension "Dev Containers" par Microsoft
Étape 1 : Créer un nouveau projet ou ouvrir un existant
Étape 2 : Ouvrir la palette de commandes
- Windows/Linux :
Ctrl+Shift+P - macOS :
Cmd+Shift+P
Étape 3 : Chercher et sélectionner
Dev Containers: Add Dev Container Configuration Files...
Étape 4 : Choisir un template
- Python 3
- Node.js
- Go
- Java
- PHP
- Ruby
- etc.
Étape 5 : VS Code crée automatiquement :
.devcontainer/
└── devcontainer.json
Étape 6 : Rouvrir dans le conteneur
- Cliquer sur le bouton vert en bas à gauche de VS Code
- Sélectionner "Reopen in Container"
{
"name": "Mon Projet Python",
"image": "mcr.microsoft.com/devcontainers/python:3.11",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance"
]
}
}
}Explications :
name: Nom de votre environnementimage: Image Docker à utiliserextensions: Extensions VS Code à installer automatiquement
.devcontainer/devcontainer.json :
{
"name": "Flask App",
"image": "mcr.microsoft.com/devcontainers/python:3.11",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"njpwerner.autodocstring"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.linting.enabled": true,
"python.formatting.provider": "black"
}
}
},
"postCreateCommand": "pip install -r requirements.txt",
"forwardPorts": [5000],
"remoteUser": "vscode"
}Explications :
postCreateCommand: Commande exécutée après la création du conteneurforwardPorts: Ports à exposer automatiquementremoteUser: Utilisateur dans le conteneur
.devcontainer/devcontainer.json :
{
"name": "Node.js App",
"image": "mcr.microsoft.com/devcontainers/javascript-node:18",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"christian-kohler.npm-intellisense"
],
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
},
"postCreateCommand": "npm install",
"forwardPorts": [3000],
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "18"
}
}
}.devcontainer/docker-compose.yml :
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres-data:/var/lib/postgresql/data
redis:
image: redis:alpine
restart: unless-stopped
volumes:
postgres-data:.devcontainer/devcontainer.json :
{
"name": "Full Stack App",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-azuretools.vscode-docker",
"mtxr.sqltools",
"mtxr.sqltools-driver-pg"
]
}
},
"postCreateCommand": "pip install -r requirements.txt",
"forwardPorts": [5000, 5432, 6379]
}.devcontainer/Dockerfile :
FROM python:3.11-slim
# Installation des dépendances système
RUN apt-get update && apt-get install -y \
git \
curl \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# Utilisateur non-root
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& apt-get update \
&& apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
USER $USERNAME
WORKDIR /workspace{
"name": "Mon Projet",
"image": "ubuntu:22.04",
// OU utiliser un Dockerfile
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
"NODE_VERSION": "18"
}
},
// OU utiliser docker-compose
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace"
}{
"onCreateCommand": "echo 'Conteneur créé'",
"updateContentCommand": "git pull",
"postCreateCommand": "npm install && npm run build",
"postStartCommand": "npm run dev",
"postAttachCommand": "echo 'Attaché au conteneur'"
}Quand sont exécutées ces commandes ?
onCreateCommand: Première création du conteneurupdateContentCommand: Quand le contenu changepostCreateCommand: Après la création (installation des dépendances)postStartCommand: À chaque démarrage du conteneurpostAttachCommand: Quand VS Code se connecte au conteneur
{
"containerEnv": {
"NODE_ENV": "development",
"API_KEY": "dev-key-123",
"DATABASE_URL": "postgresql://postgres:password@db:5432/myapp"
},
// Variables pour la machine hôte (pas le conteneur)
"remoteEnv": {
"PATH": "${containerEnv:PATH}:/custom/path"
}
}{
"mounts": [
// Monter le socket Docker (pour utiliser Docker dans Docker)
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
// Monter un cache pour npm
"source=npm-cache,target=/root/.npm,type=volume",
// Monter un dossier local
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,readonly,type=bind"
]
}{
// Ports à rediriger automatiquement
"forwardPorts": [3000, 5000, 8080],
// Configuration détaillée des ports
"portsAttributes": {
"3000": {
"label": "Frontend",
"onAutoForward": "notify"
},
"5000": {
"label": "API",
"protocol": "https"
}
},
// Ouvrir automatiquement dans le navigateur
"otherPortsAttributes": {
"onAutoForward": "openBrowser"
}
}Les features sont des scripts réutilisables pour ajouter des outils :
{
"features": {
// Installer Git
"ghcr.io/devcontainers/features/git:1": {},
// Installer Docker CLI
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest"
},
// Installer Node.js
"ghcr.io/devcontainers/features/node:1": {
"version": "18",
"nodeGypDependencies": true
},
// Installer Python
"ghcr.io/devcontainers/features/python:1": {
"version": "3.11",
"installTools": true
},
// Installer AWS CLI
"ghcr.io/devcontainers/features/aws-cli:1": {},
// Installer kubectl
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}
}
}Structure du projet :
mon-projet/
├── .devcontainer/
│ ├── devcontainer.json
│ └── docker-compose.yml
├── frontend/
│ ├── package.json
│ └── src/
├── backend/
│ ├── package.json
│ └── src/
└── docker-compose.yml (pour la production)
.devcontainer/devcontainer.json :
{
"name": "React + Node + PostgreSQL",
"dockerComposeFile": "docker-compose.yml",
"service": "workspace",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"extensions": [
// React
"dsznajder.es7-react-js-snippets",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
// Node.js
"christian-kohler.npm-intellisense",
// Database
"mtxr.sqltools",
"mtxr.sqltools-driver-pg",
// Docker
"ms-azuretools.vscode-docker"
],
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
},
"postCreateCommand": "cd frontend && npm install && cd ../backend && npm install",
"forwardPorts": [3000, 5000, 5432],
"portsAttributes": {
"3000": {
"label": "Frontend React"
},
"5000": {
"label": "Backend API"
},
"5432": {
"label": "PostgreSQL"
}
}
}.devcontainer/docker-compose.yml :
services:
workspace:
image: mcr.microsoft.com/devcontainers/javascript-node:18
volumes:
- ..:/workspace:cached
command: sleep infinity
network_mode: service:db
environment:
- DATABASE_URL=postgresql://postgres:password@localhost:5432/myapp
depends_on:
- db
db:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:.devcontainer/devcontainer.json :
{
"name": "Django + Redis + Celery",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"batisteo.vscode-django",
"wholroyd.jinja",
"mtxr.sqltools",
"mtxr.sqltools-driver-pg"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"python.languageServer": "Pylance"
}
}
},
"postCreateCommand": "pip install -r requirements.txt && python manage.py migrate",
"forwardPorts": [8000, 5432, 6379, 5555],
"portsAttributes": {
"8000": {
"label": "Django"
},
"5555": {
"label": "Celery Flower"
}
}
}Ouvrir la palette : Ctrl+Shift+P (Windows/Linux) ou Cmd+Shift+P (macOS)
Commandes Dev Containers :
Dev Containers: Reopen in Container: Ouvrir dans le conteneurDev Containers: Rebuild Container: Reconstruire le conteneurDev Containers: Rebuild Without Cache: Reconstruire sans cacheDev Containers: Reopen Locally: Revenir à l'environnement localDev Containers: Show Container Log: Voir les logs du conteneurDev Containers: Open Container Configuration: Ouvrir devcontainer.json
En bas à gauche de VS Code, vous verrez :
- 🟦 Dev Container: Nom → Vous êtes dans le conteneur
- 🔵 WSL: Ubuntu → Vous êtes sur WSL
- Rien → Vous êtes en local
Cliquer dessus ouvre un menu rapide avec les actions disponibles.
Commitez le dossier .devcontainer/ dans Git :
git add .devcontainer/
git commit -m "Add dev container configuration"
git push Maintenant, toute votre équipe peut utiliser le même environnement !
Le terminal dans VS Code s'exécute dans le conteneur :
# Dans le terminal VS Code (dans le conteneur)
python --version # Version du conteneur
npm --version # Version du conteneur
psql -U postgres -h db # Connexion à la DB Le débogueur VS Code fonctionne normalement dans le conteneur :
launch.json (pour Python) :
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py",
"FLASK_DEBUG": "1"
},
"args": ["run", "--host=0.0.0.0"],
"jinja": true
}
]
}Les extensions définies dans devcontainer.json sont installées automatiquement dans le conteneur.
Git utilise vos credentials de la machine hôte :
git pull
git add .
git commit -m "Update"
git push .devcontainer/devcontainer.json (commité dans Git) :
{
"name": "Mon Projet",
"image": "mcr.microsoft.com/devcontainers/python:3.11",
"customizations": {
"vscode": {
// Extensions obligatoires pour tous
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance"
]
}
},
"postCreateCommand": "pip install -r requirements.txt"
}.devcontainer/devcontainer.local.json (non commité, .gitignore) :
{
"customizations": {
"vscode": {
// Extensions personnelles
"extensions": [
"vscode-icons-team.vscode-icons",
"eamodio.gitlens"
]
}
}
}{
"image": "mcr.microsoft.com/devcontainers/python:3.11"
}Ces images sont optimisées pour Dev Containers et incluent des outils utiles.
# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/python:3.11
# Installation d'outils supplémentaires
RUN apt-get update && apt-get install -y \
vim \
tmux \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# Configuration personnalisée
COPY .bashrc /home/vscode/.bashrc{
"mounts": [
"source=pip-cache,target=/home/vscode/.cache/pip,type=volume",
"source=npm-cache,target=/home/vscode/.npm,type=volume"
]
}Cela accélère les installations après un rebuild.
README.md :
## Environnement de développement
Ce projet utilise VS Code Dev Containers.
### Prérequis
- Docker
- VS Code
- Extension "Dev Containers"
### Démarrage rapide
1. Cloner le projet
2. Ouvrir dans VS Code
3. Cliquer sur "Reopen in Container"
4. Attendre la construction (première fois : ~5 minutes)
5. Lancer l'application : `npm run dev`
### Services disponibles
- Frontend : http://localhost:3000
- API : http://localhost:5000
- PostgreSQL : localhost:5432{
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "18.17.0" // Version précise
}
}
}Évite les surprises avec des mises à jour.
# Reconstruire complètement
Ctrl+Shift+P → Dev Containers: Rebuild Without Cache
# Vérifier que tout fonctionne
npm install
npm run build
npm test Pour le développement : .devcontainer/
Pour la production : Dockerfile à la racine
Ne mélangez pas les deux !
GitHub Codespaces utilise la même technologie que Dev Containers, mais dans le cloud :
- Allez sur votre dépôt GitHub
- Cliquez sur "Code" → "Codespaces" → "New codespace"
- Un environnement VS Code s'ouvre dans le navigateur
- Utilise votre fichier
.devcontainer/devcontainer.json
Avantages :
- Pas besoin d'installer Docker localement
- Machine puissante dans le cloud
- Accessible depuis n'importe où
JetBrains supporte également les Dev Containers :
- Ouvrir le projet
- Aller dans "Settings" → "Docker"
- Configurer Docker
- Créer une configuration "Docker"
Sans VS Code, vous pouvez utiliser Docker Compose directement :
# Lancer les services
docker compose -f .devcontainer/docker-compose.yml up -d
# Entrer dans le conteneur
docker exec -it <container_name> bash
# Développer avec votre éditeur préféré
vim app.pyCause : Docker n'est pas démarré.
Solution :
# Vérifier que Docker tourne
docker ps
# Sous Linux
sudo systemctl start docker
# Sous macOS/Windows
Lancer Docker DesktopCauses :
- Première construction (normal)
- Connexion internet lente
- Trop de fichiers copiés
Solutions :
# .dockerignore
node_modules/
__pycache__/
.git/
*.pyc
.venv/
dist/
build/
{
"mounts": [
// Utiliser des volumes pour le cache
"source=npm-cache,target=/root/.npm,type=volume"
]
}Cause : Le code n'est pas monté correctement.
Solution :
{
"workspaceFolder": "/workspace",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind"
}Vérifier que le volume est bien monté :
docker exec -it <container> ls /workspaceSolution :
# Reconstruire le conteneur
Ctrl+Shift+P → Dev Containers: Rebuild ContainerOu installer manuellement :
code --install-extension ms-python.pythonCause : Problème d'utilisateur/groupe.
Solution dans le Dockerfile :
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
USER $USERNAMEDans devcontainer.json :
{
"remoteUser": "vscode"
}Cause : Un autre processus utilise le port.
Solution :
# Trouver le processus
lsof -i :3000
# Tuer le processus
kill <PID>Ou changer le port dans devcontainer.json :
{
"forwardPorts": [3001, 5001] // Ports différents
}Solution :
# Utiliser des images slim/alpine
FROM python:3.11-slim # Au lieu de python:3.11
# Nettoyer après installation
RUN apt-get update && apt-get install -y git \
&& rm -rf /var/lib/apt/lists/*
# Multi-stage build si nécessaire1. Ouvrir VS Code
2. Ouvrir le projet
3. VS Code se reconnecte automatiquement au conteneur
4. Commencer à coder
1. git clone <repository>
2. Ouvrir dans VS Code
3. Cliquer "Reopen in Container"
4. ☕ Attendre 2-5 minutes (première fois)
5. Commencer à coder
# Dans le terminal du conteneur
npm install <nouvelle-dépendance>
# Mettre à jour requirements.txt ou package.json
git add package.json
git commit -m "Add new dependency"
git push
# Autres développeurs
git pull
# VS Code détecte le changement et propose de rebuild# Modifier .devcontainer/devcontainer.json
# Sauvegarder
# Rebuild
Ctrl+Shift+P → Dev Containers: Rebuild Container{
"dotfiles": {
"repository": "https://github.com/username/dotfiles",
"targetPath": "/home/vscode",
"installCommand": "./install.sh"
}
}Vos configurations personnelles (.bashrc, .vimrc, etc.) sont automatiquement installées.
.devcontainer/post-create.sh :
#!/bin/bash
# Installation des dépendances
pip install -r requirements.txt
# Création de la base de données
python manage.py migrate
# Chargement des données de test
python manage.py loaddata fixtures/test_data.json
# Message de bienvenue
echo "✅ Environnement prêt ! Lancez 'python manage.py runserver'"{
"postCreateCommand": "bash .devcontainer/post-create.sh"
}devcontainer-backend.json : Configuration pour le backend
devcontainer-frontend.json : Configuration pour le frontend
devcontainer-fullstack.json : Configuration complète
Choisir le profil au démarrage.
Ne jamais commiter de secrets !
.env (gitignored) :
DATABASE_PASSWORD=secret123
API_KEY=my-secret-key
{
"runArgs": ["--env-file", ".env"]
}| Approche | Avantages | Inconvénients |
|---|---|---|
| Installation locale | Simple, rapide | Conflits, "marche sur ma machine" |
| Machines virtuelles | Isolation complète | Lourdes, lentes, gourmandes en ressources |
| Dev Containers | Léger, rapide, reproductible | Nécessite Docker |
| GitHub Codespaces | Cloud, puissant, accessible partout | Coût, connexion internet requise |
| GitPod | Cloud, gratuit (limité) | Moins flexible |
Les Dev Containers transforment votre workflow de développement :
- Installer Docker et VS Code + extension Dev Containers
- Créer
.devcontainer/devcontainer.json - Configurer l'image, extensions, commandes
- Commiter la configuration dans Git
- Ouvrir le projet dans VS Code
- Cliquer "Reopen in Container"
- Développer normalement
- Tout s'exécute dans le conteneur
✅ Onboarding rapide : 5 minutes au lieu de plusieurs heures
✅ Environnement identique : Plus de "ça marche sur ma machine"
✅ Isolation : Chaque projet dans son conteneur
✅ Reproductibilité : Partage facile avec l'équipe
✅ Nettoyage simple : Supprimer le conteneur = environnement propre
{
"name": "Mon Projet",
"image": "mcr.microsoft.com/devcontainers/python:3.11",
"customizations": {
"vscode": {
"extensions": ["ms-python.python"]
}
},
"postCreateCommand": "pip install -r requirements.txt",
"forwardPorts": [5000]
}Les Dev Containers sont devenus un standard de l'industrie pour le développement moderne. Ils éliminent les problèmes d'environnement et permettent aux équipes de se concentrer sur le code, pas sur la configuration.
🚀 Commencez avec Dev Containers dès aujourd'hui et dites adieu aux problèmes d'"environnement qui marche sur ma machine" !