Dev Containers crée un environnement de développement identique pour tous les membres de votre équipe, quel que soit leur système d’exploitation. Fini le “ça marche sur ma machine” : les dépendances, versions et configurations sont définies dans un fichier versionné. Ce guide couvre la configuration de base, Docker Compose, les features, et l’intégration CI/CD.
Le problème que Dev Containers résout
Section intitulée « Le problème que Dev Containers résout »Sans environnement standardisé, chaque développeur a sa propre configuration :
| Problème | Conséquence |
|---|---|
| Versions différentes (Node, Python…) | Bugs impossibles à reproduire |
| Dépendances système manquantes | ”Ça marche chez moi” |
| Configuration manuelle | Onboarding de plusieurs heures |
| Pollution du système local | Conflits entre projets |
Dev Containers résout ces problèmes avec Docker :
- Environnement défini en code : fichier
devcontainer.jsonversionné - Isolation complète : chaque projet a son container
- Portabilité : fonctionne sur Linux, macOS, Windows
- Onboarding instantané : clone le repo, ouvre VS Code, c’est prêt
Fonctionnement
Section intitulée « Fonctionnement »Quand vous ouvrez un projet avec Dev Containers :
- VS Code lit
.devcontainer/devcontainer.json - Docker crée le container avec l’image spécifiée
- VS Code Server s’installe dans le container
- Extensions et dépendances s’installent automatiquement
- Votre code est monté dans le container (volume)
Vous travaillez dans VS Code normalement, mais tout s’exécute dans le container : terminal, debug, LSP, extensions.
Prérequis
Section intitulée « Prérequis »-
Téléchargez depuis code.visualstudio.com.
-
Docker
Le moteur de containers qui exécute l’environnement. Installez Docker Desktop ou Docker Engine.
Fenêtre de terminal docker --version# Docker version 24.0.7 ou supérieur -
Extension Dev Containers
Installez l’extension Dev Containers (anciennement “Remote - Containers”) :
Fenêtre de terminal code --install-extension ms-vscode-remote.remote-containersOu recherchez “Dev Containers” dans le Marketplace (ID :
ms-vscode-remote.remote-containers).
Configuration de base
Section intitulée « Configuration de base »Structure des fichiers
Section intitulée « Structure des fichiers »À la racine de votre projet, créez le dossier .devcontainer/ :
mon-projet/├── .devcontainer/│ └── devcontainer.json├── src/├── package.json└── ...Exemple minimal (Node.js / Astro)
Section intitulée « Exemple minimal (Node.js / Astro) »{ "name": "Astro Dev Container", "image": "node:20-alpine3.19", "postCreateCommand": "npm ci", "customizations": { "vscode": { "extensions": [ "astro-build.astro-vscode", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode" ] } }, "forwardPorts": [4321]}Explication des champs :
| Champ | Description |
|---|---|
name | Nom affiché dans VS Code |
image | Image Docker à utiliser |
postCreateCommand | Commande exécutée après création (installation) |
customizations.vscode.extensions | Extensions à installer automatiquement |
forwardPorts | Ports exposés sur localhost |
Démarrer le container
Section intitulée « Démarrer le container »- Ouvrez le projet dans VS Code
- Appuyez sur
F1→ Dev Containers: Reopen in Container - VS Code télécharge l’image, crée le container, installe les extensions
- Votre terminal s’exécute maintenant dans le container
Vérification :
# Dans le terminal VS Code (container)node --version# v20.x.x
cat /etc/os-release | grep PRETTY_NAME# PRETTY_NAME="Alpine Linux v3.19"Propriétés du devcontainer.json
Section intitulée « Propriétés du devcontainer.json »Lifecycle commands
Section intitulée « Lifecycle commands »La spec définit plusieurs hooks exécutés à différents moments :
| Hook | Moment | Usage typique |
|---|---|---|
postCreateCommand | Après création du container | npm ci, installation dépendances |
postStartCommand | À chaque démarrage | Lancer un serveur de dev |
postAttachCommand | À chaque connexion VS Code | Messages de bienvenue |
initializeCommand | Avant création (sur l’hôte) | Clone de submodules |
Exemple avec séparation des responsabilités :
{ "postCreateCommand": "npm ci", "postStartCommand": "npm run dev -- --host"}Variables d’environnement
Section intitulée « Variables d’environnement »{ "containerEnv": { "NODE_ENV": "development", "DATABASE_URL": "postgres://user:pass@db:5432/mydb" }}Utilisateur non-root
Section intitulée « Utilisateur non-root »Par défaut, le container peut s’exécuter en root. Pour un comportement plus proche de la production :
{ "remoteUser": "node"}L’utilisateur node existe dans les images officielles Node.js. Pour d’autres images, utilisez containerUser ou créez l’utilisateur dans un Dockerfile.
Monter des fichiers/dossiers
Section intitulée « Monter des fichiers/dossiers »{ "mounts": [ "source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind,readonly" ]}Cela monte vos clés SSH dans le container pour les opérations Git.
Features : ajouter des outils sans Dockerfile
Section intitulée « Features : ajouter des outils sans Dockerfile »Les features sont des modules réutilisables qui installent des outils dans votre container. Plus propre que de tout faire dans un Dockerfile.
{ "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { "ghcr.io/devcontainers/features/node:1": { "version": "20" }, "ghcr.io/devcontainers/features/docker-in-docker:2": {}, "ghcr.io/devcontainers/features/git:1": {} }}Features populaires :
| Feature | Description |
|---|---|
node | Node.js + npm |
python | Python + pip |
docker-in-docker | Docker dans le container |
kubectl-helm-minikube | Outils Kubernetes |
terraform | Terraform CLI |
aws-cli | AWS CLI |
Consultez le catalogue de features pour la liste complète.
Docker Compose : multi-services
Section intitulée « Docker Compose : multi-services »Quand votre projet nécessite plusieurs services (base de données, cache, API), utilisez Docker Compose.
docker-compose.yml
Section intitulée « docker-compose.yml »services: web: image: node:20-alpine3.19 ports: - "4321:4321" volumes: - ./:/workspace:cached command: sleep infinity
db: image: postgres:16 restart: unless-stopped volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: myapp_user POSTGRES_PASSWORD: myapp_password POSTGRES_DB: myapp_db ports: - "5432:5432"
volumes: postgres-data:devcontainer.json pour Compose
Section intitulée « devcontainer.json pour Compose »{ "name": "Mon App + Postgres", "dockerComposeFile": "../docker-compose.yml", "service": "web", "workspaceFolder": "/workspace", "postCreateCommand": "npm ci", "forwardPorts": [4321, 5432], "customizations": { "vscode": { "extensions": [ "astro-build.astro-vscode", "ms-azuretools.vscode-docker" ] } }}Champs spécifiques à Compose :
| Champ | Description |
|---|---|
dockerComposeFile | Chemin vers le docker-compose.yml |
service | Service principal (où VS Code se connecte) |
workspaceFolder | Dossier de travail dans le container |
Accéder à la base de données
Section intitulée « Accéder à la base de données »Depuis le service web, la base de données est accessible via le nom du service :
# Dans le terminal du containerpsql -h db -U myapp_user -d myapp_dbDepuis votre machine locale, utilisez localhost:5432 grâce à forwardPorts.
Dockerfile personnalisé
Section intitulée « Dockerfile personnalisé »Pour des besoins spécifiques, créez un Dockerfile :
.devcontainer/Dockerfile
Section intitulée « .devcontainer/Dockerfile »FROM node:20-alpine3.19
# Installer des outils supplémentairesRUN apk add --no-cache \ git \ openssh-client \ curl
# Créer un utilisateur non-rootRUN adduser -D -u 1000 developerUSER developer
WORKDIR /workspacedevcontainer.json avec Dockerfile
Section intitulée « devcontainer.json avec Dockerfile »{ "name": "Custom Dev Container", "build": { "dockerfile": "Dockerfile", "context": ".." }, "remoteUser": "developer", "postCreateCommand": "npm ci", "forwardPorts": [4321]}Remote SSH + Dev Containers
Section intitulée « Remote SSH + Dev Containers »Vous pouvez combiner l’accès SSH distant avec Dev Containers : VS Code se connecte en SSH à un serveur, puis utilise Docker sur ce serveur.
-
Connectez-vous en SSH
F1→ Remote-SSH: Connect to Host → sélectionnez votre serveur -
Ouvrez le projet
Une fois connecté, ouvrez le dossier contenant
.devcontainer/ -
Ouvrez dans le container
F1→ Dev Containers: Reopen in Container
Avantages :
- Docker tourne sur le serveur (pas besoin de Docker local)
- Ressources du serveur (RAM, CPU, stockage rapide)
- Réseau du serveur (accès aux services internes)
Consultez la documentation officielle pour les configurations avancées.
Intégration CI/CD
Section intitulée « Intégration CI/CD »Le devcontainer.json peut servir de source de vérité pour votre pipeline CI.
Pattern recommandé
Section intitulée « Pattern recommandé »Dev Container = environnement de développement (VS Code) CI = job container basé sur la même image
GitHub Actions
Section intitulée « GitHub Actions »name: CI
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest container: image: node:20-alpine3.19 # Même image que devcontainer.json
steps: - uses: actions/checkout@v4
- name: Install dependencies run: npm ci
- name: Run tests run: npm test
- name: Build run: npm run buildUtiliser devcontainer CLI en CI
Section intitulée « Utiliser devcontainer CLI en CI »Pour une cohérence totale, utilisez la CLI devcontainer :
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Build dev container uses: devcontainers/ci@v0.3 with: runCmd: npm ci && npm test && npm run buildCette approche utilise exactement la configuration de votre devcontainer.json.
Performance
Section intitulée « Performance »Placement du code
Section intitulée « Placement du code »| OS | Recommandation |
|---|---|
| Linux | Code sur le filesystem Linux, performances natives |
| macOS | Préférer le code dans le container (volume nommé) pour éviter les I/O lents |
| Windows | Stocker le code en WSL2 (\\wsl$\Ubuntu\...), pas sur /mnt/c/ |
Volume nommé pour les dépendances
Section intitulée « Volume nommé pour les dépendances »Évitez de remonter node_modules depuis l’hôte :
{ "mounts": [ "source=myproject-node_modules,target=/workspace/node_modules,type=volume" ]}Cela stocke node_modules dans un volume Docker plus rapide.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| ”Cannot connect to Docker” | Docker non démarré | Lancez Docker Desktop |
| Container lent à créer | Téléchargement de l’image | Normal la première fois, cache ensuite |
| Fichiers en root sur l’hôte | remoteUser non configuré | Ajouter "remoteUser": "node" |
| Extensions non installées | Mauvais format JSON | Vérifier customizations.vscode.extensions |
| Port non accessible | forwardPorts mal placé | Doit être au premier niveau, pas dans customizations |
| Erreur “image not found” | Typo dans le nom d’image | Vérifier l’orthographe (alpine pas apline) |
Reconstruire le container
Section intitulée « Reconstruire le container »Si quelque chose ne fonctionne pas après une modification :
F1 → Dev Containers: Rebuild Container
Pour repartir de zéro (sans cache Docker) :
F1 → Dev Containers: Rebuild Container Without Cache
À retenir
Section intitulée « À retenir »- Dev Containers = environnement en code —
devcontainer.jsondéfinit tout - Spec ouverte — Fonctionne avec VS Code, Codespaces, JetBrains, DevPod
- postCreateCommand pour l’installation, postStartCommand pour les process
- Features pour ajouter des outils sans Dockerfile
- Docker Compose pour les architectures multi-services
- forwardPorts au premier niveau — pas dans
customizations - Même image en CI — garantit la cohérence dev/production
- Remote SSH + DevContainers — Docker sur le serveur distant