Aller au contenu principal
Nicolas Cousin Tech SolutionsNicolas Cousin Tech Solutions
Module 2 sur 5

Ajouter une Dev Container Feature

Rappel : le projet du module précédent

Ce module part exactement du mon-api-node du module 1 — même index.js, même devcontainer.json de base. Gardez-le ouvert.

Ce que sont les Dev Container Features

Une Feature est un script d'installation réutilisable et versionné pour un outil ou un runtime, packagé comme une image OCI publiée sur un registre de conteneurs (typiquement ghcr.io). Plutôt que d'écrire vous-même les commandes apt-get install ou de maintenir un Dockerfile personnalisé, vous référencez une Feature existante et elle s'installe automatiquement pendant la construction de l'image — indépendamment de l'image de base choisie.

Le registre officiel est consultable sur containers.dev/features. C'est là que vous trouvez, pour chaque Feature, sa référence exacte et sa version majeure disponible — ne devinez jamais cette chaîne, elle change avec le temps et une faute suffit à faire échouer le build.

Scénario : ajouter Python au projet Node

Imaginons que votre équipe ajoute un petit script Python au projet (par exemple pour traiter des données ou générer un rapport) sans vouloir faire de tout le projet une image Python. Vous gardez mcr.microsoft.com/devcontainers/javascript-node:20 comme image de base, et vous ajoutez Python en plus, via une Feature.

Vérifié sur le registre officiel au moment de la rédaction de ce module : la Feature Python officielle est référencée ghcr.io/devcontainers/features/python:1. Si vous ajoutez un autre outil que celui de cet exemple, retournez systématiquement sur containers.dev/features (ou le dépôt GitHub devcontainers/features) pour copier la référence et la version majeure exactes affichées sur la page de la Feature qui vous intéresse — ne réutilisez pas une référence trouvée ailleurs sans la revérifier.

Étape 1 — le champ features

Modifiez .devcontainer/devcontainer.json pour ajouter le champ features :

{
  "name": "Mon API Node",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "postCreateCommand": "npm install",
  "forwardPorts": [3000],
  "features": {
    "ghcr.io/devcontainers/features/python:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": ["esbenp.prettier-vscode"]
    }
  }
}

La syntaxe exacte

features est un objet, pas un tableau. Chaque clé est une référence complète au format <registre>/<espace>/<nom>:<version-majeure> — ici ghcr.io/devcontainers/features/python:1. La valeur associée est un objet d'options pour cette Feature ; {} signifie « valeurs par défaut ». Certaines Features acceptent des options (par exemple une version précise de l'outil) — la page de la Feature sur le registre documente les options disponibles pour cette Feature-là spécifiquement, ne les supposez pas identiques d'une Feature à l'autre.

Une erreur fréquente est d'oublier la version majeure après les deux-points, ou de traiter features comme un tableau de chaînes : les deux font échouer le build ou sont silencieusement ignorés selon l'erreur.

Vous pouvez aussi passer par l'interface plutôt que par le JSON directement : la palette de commandes propose Dev Containers: Configure Container Features, qui ouvre un sélecteur listant les Features du registre officiel et écrit la référence exacte à votre place dans devcontainer.json — pratique pour éviter toute faute de frappe, mais le résultat final est le même objet JSON que celui écrit à la main ci-dessus.

Étape 2 — rebuild (pas juste reopen)

Le conteneur existe déjà depuis le module 1 : une simple réouverture ne suffit pas, puisque les Features s'installent pendant la construction de l'image. Depuis la palette de commandes : Dev Containers: Rebuild Container.

VS Code reconstruit l'image en tenant compte du nouveau champ features, ce qui prend un peu plus de temps que la première ouverture (téléchargement et exécution du script d'installation Python), puis relance la fenêtre dans le conteneur reconstruit.

Étape 3 — la preuve

Ouvrez un terminal intégré (qui tourne maintenant dans le conteneur reconstruit) et vérifiez :

python3 --version

Sortie attendue : une version Python 3.x (par exemple Python 3.12.x), alors que l'image de base javascript-node:20 ne fournit pas Python nativement. Si la commande répond, la Feature s'est bien installée par-dessus l'image de base sans que vous ayez eu à toucher au Dockerfile.

Vérifiez aussi que rien n'a régressé côté Node :

node --version

Toujours la branche 20, comme au module 1 — la Feature s'ajoute à l'image de base, elle ne la remplace pas.

Ce que vous venez de faire

Vous avez ajouté un runtime complet à un conteneur existant sans écrire une seule ligne de Dockerfile, en référençant une Feature officielle avec la syntaxe exacte du registre, puis en prouvant son installation par une commande, pas par la confiance. Le fil « devcontainer » de ce parcours s'arrête ici. Au module suivant, changement complet de sujet : vous écrivez votre première configuration pre-commit multi-hooks, sur un projet différent — ce nouveau fil ne dépend de rien de ce que vous venez de faire.

Vérifiez votre compréhension

Quelle est la structure correcte du champ `features` dans devcontainer.json ?

Où faut-il vérifier la référence exacte (registre, nom, version) d'une Dev Container Feature avant de l'ajouter à un projet ?

Après avoir ajouté une Feature à devcontainer.json, quelle action est nécessaire pour qu'elle soit installée ?

Envie d'être prévenu des prochains modules ?

L'Académie reste gratuite et en accès libre, sans inscription. Si vous voulez juste être averti par email à la sortie d'un nouveau module, c'est ici — aucune obligation, désinscription en un clic.