13 minute read

un développeur assis à son bureau @wildagsx

Depuis maintenant de nombreuses annĂ©es, j’ai dans ma todo liste le test des Dev Containers. Les Dev Containers c’est quoi ? En deux mots, cela vous permet de configurer votre environnement de dĂ©veloppement dans une image Docker (ou toute autre solution de gestion de conteneurs).

Pour quelle raison me direz-vous đŸ€” ?

Eh bien dĂ©jĂ  parce que c’est rigolo Ă  faire (ne jamais sous estimer la cĂŽtĂ© fun & geek 😉) et ensuite car cela peut rendre bien des services. Je viens de changer de machine et, du coup, c’était le moment parfait : soit je rĂ©installe tout sur ma machine, soit je trouve un moyen de ne pas installer tout et n’importe quoi et de rentrer dans l’enfer des compatibilitĂ©s des logiciels pour le dev.

C’est lĂ , pour moi, le grand plus de Dev Containers : permettre d’avoir plusieurs configurations de dĂ©veloppement sans des problĂšmes de collisions ou de devoir installer des outils pour gĂ©rer plusieurs versions d’un mĂȘme SDK par exemple.

Dans mon cas je peux citer Java bien sûr, mais aussi NodeJS, Python, Ruby, 


L’objectif est le mĂȘme pour toutes ces technologies : ne pas avoir Ă  jongler entre les diffĂ©rentes versions selon mon besoin.

L’autre aspect, et nous y reviendrons plus tard, est la possibilitĂ© aussi d’avoir besoin de faire des modifications sur un projet sans ĂȘtre sur sa machine habituelle. LĂ  encore, les Dev Containers offrent la possibilitĂ© de rendre portable notre environnement de dĂ©veloppement. On retrouve la philosophie des CDE (Cloud Development Environments) : permettre le dĂ©marrage d’un environnement de dĂ©veloppement prĂȘt Ă  l’emploi pour un projet avec la configuration as code et donc qui suit parfaitement le cycle de vie du projet. Les CDE, d’ailleurs, lorgnent de plus en plus vers la compatibilitĂ© avec les Dev Containers.

Le dernier exemple que l’on peut aussi donner concerne les projets Open Source. Quel enfer de passer plusieurs heures pour avoir une configuration qui permet de compiler et tester le projet ! Les Dev Containers permettent d’éviter cette douloureuse phase.

⚗ Le POC : mon blog

Le billet de blog que vous ĂȘtes en train de lire a comme base Jekyll, lui-mĂȘme basĂ© sur Ruby.

Ruby, je n’en fait pas et le seul moment oĂč j’en ai besoin c’est pour mon blog. Clairement, je n’ai pas un gros besoin d’avoir tout le tooling continuellement installĂ© et Ă  jour sur ma machine. C’est un exemple parfait, pour moi, de l’utilisation des Dev Containers. J’ai besoin d’installer Ruby, puis un bundler, et enfin Jekyll lui-mĂȘme. Rien de bien compliquĂ©, ce qui m’arrange pour commencer mon exploration des Dev Containers đŸ§‘â€đŸ’».

đŸ§‘â€đŸ’» L’IDE : VSCode

On ne va pas se mentir, utiliser les Dev Containers en dehors de VSCode n’est pas une chose aisĂ©e 
 C’est peut ĂȘtre le premier warning Ă  noter : si vous aimer utiliser d’autres IDE vous allez pouvoir faire des choses avec la CLI par exemple, mais pour moi l’expĂ©rience dĂ©veloppeur est la meilleure dans VSCode.

A noter que Intellij de JetBrains permet une intĂ©gration des Dev Container dans sa version ultimate, je ne l’ai pas encore testĂ©e.

Cette restriction d’intĂ©gration ou plutĂŽt cette facilitĂ© d’intĂ©gration peut ĂȘtre un premier choix d’utiliser ou non les Dev Containers. Je pense que le mieux est de voir si le jeu en vaut la chandelle en termes de use case. A titre d’exemple, je donne pas mal de confĂ©rences ou fait pas mal de dĂ©mos, c’est une bonne chose de pouvoir figer son environnement de dĂ©veloppement et qu’il soit reproductible Ă  loisir.

L’intĂ©gration des Dev Container Ă  VSCode est native, il n’y a rien Ă  installer. Si votre VSCode n’a pas l’extension d’installĂ©e, il suffit de l’installer via ce lien.

Ensuite, rien Ă  faire, l’extension reconnaĂźtra automatiquement les fichiers Dev Container lorsqu’ils sont prĂ©sents dans le projet.

⚙ Initialisation de la configuration

Pour initialiser votre configuration autant utiliser VSCode et son extension : CMD+SHIFT+P puis Dev Containers: Add Dev Containers configuration Files.... Ensuite, je vous conseille de choisir de mettre la configuration dans le workspace du projet afin d’avoir une configuration propre au projet (souvenez-vous : la reproductibilitĂ© d’un environnement 😉). Et lĂ , il vous suffit de choisir une configuration (en fait une image Docker), correspondant Ă  votre besoin, dans mon cas : Jekyll. Ensuite vous pouvez avoir le choix d’une version de l’image en particulier, dans le cas de Jekyll quelle version de Debian. Puis, potentiellement des features Ă  activer.

Une feature, en deux mots, est une portion de configuration avec ou non un outil dĂ©jĂ  prĂ©-configurĂ© dans votre image. A titre d’exemple : si vous souhaitez avoir la CLI de GitHub, il existe une feature qui vous permettra qu’elle soit prĂ©sente dans votre image sans avoir Ă  le faire manuellement et Ă  gĂ©rer ses potentielles mises Ă  jour (les features sont versionnĂ©es). Nous verrons comment les utiliser plus en avant dans cet article.

Dans mon cas je vais commencer simple : juste la configuration pour faire du Jekyll. Et Ă  la fin, VSCode vous propose de rĂ©-ouvrir votre projet avec la configuration du Dev Container qu’il vient de crĂ©er.

⚠ A ce stade je dois vous indiquer un nouveau warning : Dev Container demande d’avoir un logiciel de run et construction d’images de conteneurs, dans mon cas j’utilise Docker mais n’oubliez pas que c’est un prĂ©-requis fort 😉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/jekyll
{
  "name": "Jekyll",
  // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
  "image": "mcr.microsoft.com/devcontainers/jekyll:2-bullseye"

  // Features to add to the dev container. More info: https://containers.dev/features.
  // "features": {},

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // "forwardPorts": [],

  // Uncomment the next line to run commands after the container is created.
  // "postCreateCommand": "jekyll --version"

  // Configure tool-specific properties.
  // "customizations": {},

  // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
  // "remoteUser": "root"
}

Voici ce que donne le fichier fraĂźchement crĂ©Ă© par l’extension VSCode. On voit ici qu’il y a des options que l’on peut paramĂ©trer et / ou activer. On reviendra sur certaines d’entre elles plus loin dans cet article ou dans les suivants.

✍ Utilisation

VSCode vous propose de rĂ©-ouvrir votre projet en mode Dev Container. Si ce n’est pas le cas c’est possible via l’extension : CMP+SHIFT+P puis Dev Containers: Open Container Configuration File
 vous vous retrouvez 
 dans votre VSCode comme si rien n’avait changĂ© !

Vous remarquez peut-ĂȘtre un changement dans votre terminal : vscode ➜ /workspaces/blog (dev-container) $. Et aussi en bas Ă  gauche de VSCode vous voyez, par exemple Dev Container: Jekyll @ desktop-linux. En rĂ©alitĂ©, les Dev Containers ne sont (avec des gros guillemets) qu’un vscode server local. On comprends mieux pourquoi les CDE s’y intĂ©ressent et, pour certains, offrent une compatibilitĂ© pour les rĂ©utiliser.

Ensuite, je peux utiliser comme bon me semble cet environnement en installant mes outils et autres SDK dont j’ai besoin, sans polluer ma machine :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ gem install jekyll bundler
Successfully installed jekyll-4.3.4
Fetching bundler-2.6.2.gem
Successfully installed bundler-2.6.2
2 gems installed

A new release of RubyGems is available: 3.5.23 → 3.6.2!
Run `gem update --system 3.6.2` to update your installation.

$ bundle exec jekyll serve
To use retry middleware with Faraday v2.0+, install `faraday-retry` gem
/usr/local/rvm/gems/default/gems/httpclient-2.8.3/lib/httpclient.rb:19: warning: mutex_m was loaded from the standard library, but will no longer be part of the default gems starting from Ruby 3.4.0.
You can add mutex_m to your Gemfile or gemspec to silence this warning.
Configuration file: /workspaces/blog/_config.yml
            Source: /workspaces/blog
       Destination: /workspaces/blog/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
      Remote Theme: Using theme mmistakes/minimal-mistakes
       Jekyll Feed: Generating feed for posts
                    done in 3.679 seconds.
 Auto-regeneration: enabled for '/workspaces/blog'
    Server address: http://127.0.0.1:4000
  Server running... press ctrl-c to stop.

Une chose trĂšs intĂ©ressante avec les Dev Containers et l’extension de VSCode : le forward de ports est automatiquement gĂ©rĂ© ! Pas de configuration compliquĂ©e pour accĂ©der Ă  ce qui est exposĂ© par mon container, comme on le voit mon blog est disponible sur l’URL locale http://127.0.0.1:4000 😍.

đŸ’» L’avantage du mode local

Tout ce que vous faĂźtes dans vos fichiers n’est pas une copie de vos fichiers dans votre container mais bien sur vos fichiers directement de votre machine, pas de synchro Ă  prĂ©voir et pas de lock sur l’environnement Dev Container (c’est un volume montĂ© sur l’image Docker). Vous pouvez toujours Ă©diter localement vos fichiers. C’est une grosse diffĂ©rence avec le mode SSH et un vscode server remote.

Autre chose trĂšs appreciable : c’est votre machine, votre VSCode mais aussi votre configuration Git qui est utilisĂ©e, pas de synchro Ă  faire lĂ  non plus. Les commandes git et aussi les push utilisent vos configurations locales, dans mon cas, par exemple, la signature des commits et les credentials de mon compte GitHub 😎.

⚙ Le paramĂ©trage

âšĄïž ExĂ©cution de commandes au dĂ©marrage

Les Dev Containers permettent d’aller plus loin dans le paramĂ©trage de votre environnmenet. Imaginons que je souhaite lancer Jekyll au dĂ©marrage de mon environnement. Il y a plusieurs façons de le faire, l’une d’elle est d’utiliser l’option postCreateCommand dans le devcontainer.json prĂ©cĂ©demment crĂ©Ă©.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/jekyll
{
  "name": "Jekyll",
  // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
  "image": "mcr.microsoft.com/devcontainers/jekyll:2-bullseye",

  // Features to add to the dev container. More info: https://containers.dev/features.
  // "features": {},

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // "forwardPorts": [],

  // Uncomment the next line to run commands after the container is created.
  "postCreateCommand": "bundle exec jekyll serve"

  // Configure tool-specific properties.
  // "customizations": {},

  // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
  // "remoteUser": "root"
}

J’en profite pour faire une petite digression Ă  ce stade : si vous avez suivi les Ă©tapes de cet article au moment d’enregistrer le fichier devcontainer.json l’extension VSCode vous propose de reconstruire votre environnement et de le relancer. Pratique non ? 😎 Comme toujours si cela n’apparaĂźt pas ou si vous n’avez pas le temps de cliquer : CMD+SHIFT+P puis Dev Containers: Rebuild container...

✹ Customisation de l’IDE

Une des choses sympas dans les options possibles est la partie permettant la customisation propre au type d’IDE que vous utilisez. Dans mon cas, pour cet exemple, c’est VSCode mais vous avez plusieurs supports (voir la documentation). Imaginons, que dans mon cas, je souhaite avoir Prettier, une extension permettant le formatage de code source dans de nombreux langages. Je prends cet exemple Ă  dessein car pour faciliter les diffs de code source, cela peut ĂȘtre avantageux de partager le mĂȘme outil et la mĂȘme configuration de mise en forme 😉.
Je pourrai trĂšs bien, Ă  chaque lancement de mon Dev Containers, aller dans la vue extensions de VSCode et activer l’extension. Cela fonctionne mais cela fait des cliques et si une autre personne utilise mon projet je suis dĂ©pendant qu’elle l’active, dans la bonne version et de la façon que je souhaite. C’est lĂ  oĂč on va retrouver ce qui a fait ses preuves depuis pas mal d’annĂ©es maintenant : la configuration as code 😉.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/jekyll
{
  "name": "Jekyll",
  // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
  "image": "mcr.microsoft.com/devcontainers/jekyll:2-bullseye",

  // Features to add to the dev container. More info: https://containers.dev/features.
  // "features": {},

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // "forwardPorts": [],

  // Uncomment the next line to run commands after the container is created.
  "postCreateCommand": "bundle exec jekyll serve",

  // Configure tool-specific properties.
  "customizations": {
    // Configure properties specific to VS Code.
    "vscode": {
      "settings": { "editor.formatOnSave": true },
      "extensions": ["esbenp.prettier-vscode"]
    }
  }

  // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
  // "remoteUser": "root"
}

🔎 Vous retrouverez l’identifiant unique de l’extension dans le market place dans les informations de l’extension.

Dans cet exemple, j’ai activĂ© l’extension Prettier mais aussi modifiĂ© le comportement de VSCode pour qu’il appelle le formateur Ă  chaque sauvegarde.

đŸ› ïž Outillage

Je vous l’ai dĂ©jĂ  dis, les images prĂ©-packagĂ©e viennent avec leur outils respectifs (Ruby par exemple dans mon cas). Cependant il peut vous manquer des outils qui vous sont nĂ©cessaires et lĂ  encore, les installer manuellement Ă  chaque fois n’est pas une chose agrĂ©able et optimisĂ©e. Les Dev Containers viennent avec deux maniĂšres de le faire : crĂ©er sa propre image ou utiliser la notion de features. Nous verrons la crĂ©ation d’image dans un autre article sur l’utilisation plus avancĂ©e des Dev Containers, concentrons nous sur la notion de features. Les features permettent donc d’enrichir votre Dev Container via un catalogue de features. Nous allons voir comment les utiliser et comment les paramĂ©trĂ©es au mieux pour rĂ©pondre Ă  nos besoins 😉.

Imaginons que je veuille installer l’outil JQ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/jekyll
{
	"name": "Jekyll",
	// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
	"image": "mcr.microsoft.com/devcontainers/jekyll:2-bullseye",

	// Features to add to the dev container. More info: https://containers.dev/features.
	"features": {
    "ghcr.io/eitsupi/devcontainer-features/jq-likes:1": {
        "jqVersion": "latest"
    }
	},
	// Use 'forwardPorts' to make a list of ports inside the container available locally.
	// "forwardPorts": [],

	// Uncomment the next line to run commands after the container is created.
	"postCreateCommand": "bundle exec jekyll serve",

	// Configure tool-specific properties.
	"customizations": {
		// Configure properties specific to VS Code.
		"vscode": {
			"settings": {"editor.formatOnSave": false},
			"extensions": ["esbenp.prettier-vscode"]
		}
	}

	// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
	// "remoteUser": "root"
}

Dans ce cas on active une feature avec son nom et on peut, si elle le supporte, lui ajouter des paramĂštres, dans mon cas la version de JQ.

A ce stade de la dĂ©couverte des Dev Containers je n’irai pas plus loin sur l’explication des paramĂštres. Ce sont ceux proposĂ©s par dĂ©faut mais il en existe une longue liste en fonction de vos besoins. La documentation sera votre meilleure alliĂ©e 😉.

đŸȘ« Et la performance ?

Pour l’écriture de cet article, j’utilise un Mac Book M3 avec 24 Go de mĂ©moire. Pour ĂȘtre honnĂȘte ne je vois pas du tout de diffĂ©rence avec une installation locale. Encore une fois, ce premier besoin est simple et ne demande pas forcĂ©ment une grosse configuration et beaucoup d’outillage. A voir ce que cela donne quand je vais faire du Java 😉.

Autre chose que l’on peut se poser comme question est la taille des images versus la taille de tout installer sur une machine. Pour l’image que j’utilise pour la partie Jekyll elle fait 2.4 Go ! C’est plutĂŽt imposant si on compare ce que l’on doit installer qui se rĂ©sume simplement Ă  Ruby et quelques dĂ©pendances !

C’est une chose Ă  prendre en compte : cela va forcĂ©ment vous ajouter ce genre de sur-consommation mĂ©moire et disque. Il est toujours possible de faire rĂ©guliĂšrement le mĂ©nage des images non utilisĂ©es mais dans tous les cas cela ne sera pas adaptĂ© aux petites configurations mĂ©moires et disques.

Pour minimiser l’impact sur votre machine vous pouvez vous tourner vers les Cloud Development Environments qui sont compatibles avec les Dev Containers. Un des plus connus : Code Spaces de GitHub. Cela va vous permettre de n’utiliser que votre navigateur ou votre VSCode local (mais simplement pour la partie IDE et non pas le shell qui va utiliser les ressources distantes). Comme d’habitude, si cela vous permet de bĂ©nĂ©ficier de configurations supĂ©rieures Ă  votre machine attention Ă  la facturation !

En conclusion

J’espĂšre que cette dĂ©couverte en ma compagnie des Dev Containers vous a plus. Dans les autres parties on plongera un plus en profondeur dans la customisation d’images pour rĂ©pondre au mieux Ă  vos besoins 😉.

Si vous ĂȘtes arrivĂ©s jusque lĂ  merci de m’avoir lu et si il y a des coquilles n’hĂ©sitez pas Ă  me faire une issue ou PR 😊.

Merci à ma relectrice, Fanny, qui vous permet de lire cet article sans avoir trop les yeux qui saignent 😘.

Comments