Ga naar hoofdinhoud

Devcontainers

Op deze pagina zet je je volledige ontwikkelomgeving op voor de labo's en het project. Eerst lees je waarom we met devcontainers werken, daarna volg je het stappenplan. Loopt er iets mis? Kijk dan bij Troubleshooting.

Wat heb je op het einde van deze pagina?

Een private labo-repository op GitHub, die je in VS Code opent in een devcontainer met Node.js en TypeScript. Je installeert daarvoor niets anders dan Docker, Git en VS Code op je eigen computer.

Waarom devcontainers?

Wat is een dev environment?

Een Dev Environment (ontwikkelomgeving) is simpelweg een systeem waar alle software, tools en hardware op geïnstalleerd zijn, zodat jij kunt programmeren aan een specifiek project. Met software en tools wordt echt alles bedoeld dat je gebruikt tijdens het programmeren:

  • Code editors, bv. VS Code of Visual Studio
  • Plugins, bv. een Markdown extension in VS Code
  • Compilers, bv. de .NET compiler voor C#
  • Sandbox omgevingen, bv. Node.js
  • ...

Meestal heb je op één toestel meerdere Dev Environments geïnstalleerd. Het is nu eenmaal niet praktisch om rond te lopen met 5 laptops...

Wat kan er misgaan?

Een Dev Environment is dus vaak een complex systeem van allerlei software, tools en specifieke instellingen die samenwerken. Een paar herkenbare scenario's:

Oh nee, mijn laptop is kapot!

Je koopt een nieuwe en moet alle software opnieuw installeren, in exact dezelfde versie. Weet jij nog of je versie 18.17.1 of 17.9.2 had?

Oh nee, een groepswerk!

Het project werkt perfect bij jou, maar wil niet draaien bij je teamgenoot. Tijd om elke tool na te kijken op versienummer!

Oh nee, een oud project werkt niet meer!

Je hebt Node.js geüpdatet voor je nieuwste project. Oeps, je oude projecten die een oudere versie nodig hebben, werken niet meer.

Deployment hell

Alles werkt bij jou en je teamgenoten, maar niet op de server. Opnieuw alle versienummers nakijken...

Docker to the rescue!

We kunnen een Docker Container zo samenstellen dat alle tools en instellingen daarin geïnstalleerd staan. Je installeert niets meer op je eigen systeem, alles zit netjes verpakt in een Docker Container! Zo'n Docker Container waarin je je Dev Environment opslaat voor één specifiek project, dàt heet een DevContainer.

Jouw computer
VS Code + Dev Containers extensie
Docker Desktop
Devcontainer
Node.js + TypeScript
ts-node
Code van je labo-repo
GitHub

labo-repository

Op je eigen computer staan dus enkel VS Code, Docker en Git. Alles wat specifiek is voor het project, zit in de devcontainer.

Stappenplan in één oogopslag

Volg de stappen in deze volgorde. Klik op een stap om er meteen naartoe te springen.

Stap 1: Installeer de software

WSL installeren

Enkel voor Windows

Docker Desktop heeft WSL (Windows Subsystem for Linux) nodig op Windows. Werk je op een andere computer, dan sla je deze stap over.

Open PowerShell als administrator en kijk na of WSL al geïnstalleerd is, en zo ja, welke versie:

wsl --version
Voorbeeld van de output als WSL geïnstalleerd is

Je versienummers kunnen verschillen.

WSL version: 2.4.10.0
Kernel version: 5.15.167.4
WSLg version: 1.0.65
MSRDC version: 1.2.5620
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26100.3037

Afhankelijk van het resultaat voer je één van deze commando's uit:

SituatieCommando
WSL is al geïnstalleerdwsl --update
WSL is niet geïnstalleerdwsl --install --no-distribution

Meer informatie vind je op learn.microsoft.com.

Docker Desktop installeren

Download het installatieprogramma via docker.com en voer het uit.

Geen account nodig

Je hoeft GEEN account te maken om Docker Desktop te installeren. Maak je er toch één aan, kijk dan in je mailbox naar de verificatiemail en bevestig je e-mailadres. Anders start je devcontainer later niet op (zie Troubleshooting).

Git installeren en configureren

Download het installatieprogramma via git-scm.com en voer het uit.

Vergeet Git niet te configureren

Na de installatie moet je Git nog vertellen wie je bent, met je naam en e-mailadres. Zonder die instellingen kan je niet committen. Hoe je dat doet, lees je op de Git-pagina onder Git configureren.

Stap 2: Zet GitHub klaar

Maak een GitHub-account aan

Maak een GitHub-account aan met je AP e-mailadres, of log in op je bestaande account.

Al een persoonlijk GitHub-account?

Maak dan geen tweede account aan. Voeg je AP e-mailadres toe als secundair adres in de instellingen. Meerdere accounts zorgen vaak voor problemen.

Maak een labo-repository aan

  1. Ga naar GitHub en zorg dat je ingelogd bent.
  2. Klik op de tab Repositories en vervolgens op New repository.
  3. Geef je labo-repository een naam, bv. webontwikkeling-labo.
  4. Kies voor een Private repository. De rest van de instellingen laat je op de standaardwaarden staan. Klik op Create repository.

Stap 3: Stel Visual Studio Code in

Installeer Visual Studio Code

Download het installatiebestand via code.visualstudio.com en voer het uit.

VS Code extensies

Open Visual Studio Code en open de Extensions-tab in de sidebar. Installeer deze twee extensies:

Remote Development

Extension pack van Microsoft dat 4 extensies installeert voor ontwikkeling in devcontainers.
Bekijk in de Marketplace

GitHub Pull Requests

Koppelt VS Code aan je GitHub-account, zodat je kan aanmelden en met je repositories kan werken.
Bekijk in de Marketplace

Authenticeer met GitHub in VS Code

  1. Klik in Visual Studio Code in de linkeronderhoek op het avatar-icoontje.

    Het Accounts-menu linksonder in VS Code

    De positie van het Accounts menu

  2. Kies Sign in to GitHub to use GitHub Pull Requests.

  3. Er opent een browservenster dat je vraagt om te authenticeren. Meld je aan met je GitHub-account.

Pro tip

In hetzelfde menu vind je ook Sign in to sync settings. Daarmee worden al je VS Code-instellingen gesynchroniseerd met GitHub. Installeer je ooit VS Code op een andere computer, dan krijgt die automatisch dezelfde instellingen.

Stap 4: Maak je devcontainer aan

Labo devcontainer aanmaken

Zoek de labo-repository die je eerder aanmaakte op in GitHub en volg deze stappen:

  1. Kopieer de HTTPS Git URL via de groene Code-knop op de repo-pagina.

  2. Open VS Code.

  3. Open het Command Palette met CTRL + SHIFT + P.

  4. Zoek naar het command Dev Containers: Clone Repository in Container Volume... en druk Enter.

  5. Plak de HTTPS Git URL die je kopieerde en druk Enter.

  6. Beantwoord de vragen die VS Code stelt:

    VS Code vraagt naar...Jij kiest
    Branchmain
    Container templateNode JS & Typescript
    Versie van Node.js24-trixie
  7. De devcontainer wordt opgestart en je kan beginnen. Kijk zeker na dat je een bestand kan pushen naar de repository.

Even geduld

De eerste keer opstarten duurt een tijdje, omdat Docker de image moet downloaden. Daarna gaat het een pak sneller.

Controleer je configuratie

Open het bestand .devcontainer/devcontainer.json. De gemarkeerde regels tonen de keuzes die je net maakte:

.devcontainer/devcontainer.json
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & TypeScript",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:5-24-trixie",
"features": {}

// 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": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",

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

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
Checklist: ben je klaar?
  • ✅ De devcontainer start op in VS Code.
  • .devcontainer/devcontainer.json bevat de image typescript-node:5-24-trixie.
  • ✅ Je kan een bestand committen en pushen naar je labo-repository.

Troubleshooting

Zoek je probleem op in de tabel en klik door naar de oplossing.

ProbleemOplossing
Clonen van je private repo lukt niet, of je wordt met het verkeerde account aangemeldMeerdere GitHub-accounts
Foutmelding dat je WSL-versie niet up-to-date isWSL-versie is niet up-to-date
Devcontainer start niet door een Wayland- of WSLg-mountWayland-socket uitschakelen
Devcontainer start niet en je hebt een Docker-accountDocker e-mailadres niet geverifieerd
Foutmelding dat virtualisatie niet ingeschakeld isVirtualisatie is niet ingeschakeld in BIOS

Meerdere GitHub-accounts

Als je meerdere GitHub-accounts hebt, kan het zijn dat je problemen ondervindt bij het clonen van je private repo: je computer probeert dan in te loggen met het verkeerde account.

Oplossing: verwijder je GitHub-account uit de Windows Credential Manager. Zoek in Windows naar "Credential Manager" (in het Nederlands: Aanmeldingsgegevensbeheer of Referentiebeheer) en verwijder alle credentials die beginnen met git:https://github.com.

Voorkomen: gebruik slechts één GitHub-account. Je kan meerdere e-mailadressen toevoegen aan je GitHub-account, dus je kan je AP e-mailadres gewoon toevoegen aan je persoonlijke account.

WSL-versie is niet up-to-date

Je probeert de devcontainer te openen, maar krijgt een foutmelding dat je WSL-versie niet up-to-date is.

Oplossing:

  1. Open PowerShell als administrator (rechtermuisknop op het PowerShell-icoontje, kies Run as Administrator).

  2. Voer de volgende commando's uit:

    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    wsl --set-default-version 2
    wsl --update
  3. Herstart je computer om zeker te zijn dat alles goed werkt.

Wayland-socket uitschakelen

Start je devcontainer op Windows met WSL niet op en verwijst de foutmelding naar een mount met wayland, WSLg of \\wsl.localhost\? VS Code probeert dan mogelijk een socket voor grafische Linux-applicaties aan de container te koppelen. Voor onze Node.js- en TypeScript-oefeningen is die koppeling niet nodig.

Voorbeeld van de foutmelding en volledige stacktrace

De paden en versienummers kunnen op jouw computer verschillen.

[2023-09-19T10:31:18.520Z] docker: Error response from daemon: \\wsl.localhost\Ubuntu-20.04\mnt\wslg\runtim
e-dir\wayland-0%!(EXTRA string=is not a valid Windows path).
See 'docker run --help'.
[2023-09-19T10:31:18.611Z] Stop (546 ms): Run: docker run --sig-proxy=false -a STDOUT -a STDERR --mount source=c:\Users\someone\projects\app1,target=/workspace,type=bind,consistency=cached --mount type=volume,src=vscode,dst=/vscode --mount type=bind,src=\\wsl.localhost\Ubuntu-20.04\mnt\wslg\runtime-dir\wayland-0,dst=/tmp/vscode-wayland-0e3c539d-fff8-4b07-beee-268f1d0b7d0e.sock -l devcontainer.local_folder=c:\Users\someone\projects\app1 -l devcontainer.config_file=c:\Users\someone\projects\app1\.devcontainer\devcontainer.json --entrypoint /bin/sh -l devcontainer.metadata=[{"id":"ghcr.io/devcontainers/features/common-utils:2"},{"id":"ghcr.io/devcontainers/features/git:1"},{"id":"ghcr.io/devcontainers/features/node:1","customizations":{"vscode":{"extensions":["dbaeumer.vscode-eslint"]}}},{"customizations":{"vscode":{"extensions":["dbaeumer.vscode-eslint"]}},"remoteUser":"node"},{"id":"ghcr.io/devcontainers/features/git:1"},{"customizations":{"vscode":{"extensions":["dbaeumer.vscode-eslint"]}},"remoteUser":"node"},{"mounts":[]}] mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye -c echo Container started
[2023-09-19T10:31:18.613Z] Start: Run: docker ps -q -a --filter label=devcontainer.local_folder=c:\Users\someone\projects\app1 --filter label=devcontainer.config_file=c:\Users\someone\projects\app1\.devcontainer\devcontainer.json
[2023-09-19T10:31:18.626Z] Stop (593 ms): Run: docker events --format {{json .}} --filter event=start
[2023-09-19T10:31:18.949Z] Stop (336 ms): Run: docker ps -q -a --filter label=devcontainer.local_folder=c:\Users\someone\projects\app1 --filter label=devcontainer.config_file=c:\Users\someone\projects\app1\.devcontainer\devcontainer.json
[2023-09-19T10:31:18.953Z] Error: Command failed: docker run --sig-proxy=false -a STDOUT -a STDERR --mount source=c:\Users\someone\projects\app1,target=/workspace,type=bind,consistency=cached --mount type=volume,src=vscode,dst=/vscode --mount type=bind,src=\\wsl.localhost\Ubuntu-20.04\mnt\wslg\runtime-dir\wayland-0,dst=/tmp/vscode-wayland-0e3c539d-fff8-4b07-beee-268f1d0b7d0e.sock -l devcontainer.local_folder=c:\Users\someone\projects\app1 -l devcontainer.config_file=c:\Users\someone\projects\app1\.devcontainer\devcontainer.json --entrypoint /bin/sh -l devcontainer.metadata=[{"id":"ghcr.io/devcontainers/features/common-utils:2"},{"id":"ghcr.io/devcontainers/features/git:1"},{"id":"ghcr.io/devcontainers/features/node:1","customizations":{"vscode":{"extensions":["dbaeumer.vscode-eslint"]}}},{"customizations":{"vscode":{"extensions":["dbaeumer.vscode-eslint"]}},"remoteUser":"node"},{"id":"ghcr.io/devcontainers/features/git:1"},{"customizations":{"vscode":{"extensions":["dbaeumer.vscode-eslint"]}},"remoteUser":"node"},{"mounts":[]}] mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye -c echo Container started
[2023-09-19T10:31:18.953Z] trap "exit 0" 15
[2023-09-19T10:31:18.953Z] exec "$@"
[2023-09-19T10:31:18.953Z] while sleep 1 & wait $!; do :; done -
[2023-09-19T10:31:18.954Z] at gAA (c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js:462:1066)
[2023-09-19T10:31:18.954Z] at FK (c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js:462:1002)
[2023-09-19T10:31:18.954Z] at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
[2023-09-19T10:31:18.954Z] at async FAA (c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js:479:3660)
[2023-09-19T10:31:18.954Z] at async GC (c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js:479:4775)
[2023-09-19T10:31:18.954Z] at async VeA (c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js:611:12240)
[2023-09-19T10:31:18.954Z] at async WeA (c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js:611:11981)
[2023-09-19T10:31:18.972Z] Stop (2845 ms): Run: C:\Users\someone\AppData\Local\Programs\Microsoft VS Code\Code.exe --ms-enable-electron-run-as-node c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js up --user-data-folder c:\Users\someone\AppData\Roaming\Code\User\globalStorage\ms-vscode-remote.remote-containers\data --container-session-data-folder /tmp/devcontainers-07b5c790-2533-49ff-8a65-9d12776720f61695119468050 --workspace-folder c:\Users\someone\projects\app1 --workspace-mount-consistency cached --id-label devcontainer.local_folder=c:\Users\someone\projects\app1 --id-label devcontainer.config_file=c:\Users\someone\projects\app1\.devcontainer\devcontainer.json --log-level debug --log-format json --config c:\Users\someone\projects\app1\.devcontainer\devcontainer.json --default-user-env-probe loginInteractiveShell --mount type=volume,source=vscode,target=/vscode,external=true --mount type=bind,source=\\wsl.localhost\Ubuntu-20.04\mnt\wslg\runtime-dir\wayland-0,target=/tmp/vscode-wayland-0e3c539d-fff8-4b07-beee-268f1d0b7d0e.sock --skip-post-create --update-remote-user-uid-default on --mount-workspace-git-root true
[2023-09-19T10:31:18.972Z] Exit code 1
[2023-09-19T10:31:18.978Z] Command failed: C:\Users\someone\AppData\Local\Programs\Microsoft VS Code\Code.exe --ms-enable-electron-run-as-node c:\Users\someone\.vscode\extensions\ms-vscode-remote.remote-containers-0.309.0\dist\spec-node\devContainersSpecCLI.js up --user-data-folder c:\Users\someone\AppData\Roaming\Code\User\globalStorage\ms-vscode-remote.remote-containers\data --container-session-data-folder /tmp/devcontainers-07b5c790-2533-49ff-8a65-9d12776720f61695119468050 --workspace-folder c:\Users\someone\projects\app1 --workspace-mount-consistency cached --id-label devcontainer.local_folder=c:\Users\someone\projects\app1 --id-label devcontainer.config_file=c:\Users\someone\projects\app1\.devcontainer\devcontainer.json --log-level debug --log-format json --config c:\Users\someone\projects\app1\.devcontainer\devcontainer.json --default-user-env-probe loginInteractiveShell --mount type=volume,source=vscode,target=/vscode,external=true --mount type=bind,source=\\wsl.localhost\Ubuntu-20.04\mnt\wslg\runtime-dir\wayland-0,target=/tmp/vscode-wayland-0e3c539d-fff8-4b07-beee-268f1d0b7d0e.sock --skip-post-create --update-remote-user-uid-default on --mount-workspace-git-root true
[2023-09-19T10:31:18.978Z] Exit code 1

Oplossing:

  1. Open de instellingen van VS Code met Ctrl + , of via File > Preferences > Settings. Kies de tab User, zodat je de lokale gebruikersinstellingen aanpast.
  2. Zoek naar dev.containers.mountWaylandSocket.
  3. Vink Dev Containers: Mount Wayland Socket uit. De instelling staat nu op false.
  4. Krijg je ook een fout over de GPU? Zoek dan naar dev.containers.gpuAvailability en zet Dev Containers: GPU Availability op none. Deze stap is optioneel.
  5. Open het Command Palette met F1 of Ctrl + Shift + P, kies Dev Containers: Rebuild Container en druk op Enter.
  6. Controleer de nieuwe opstartlog via Dev Containers: Show Container Log. De --mount-optie voor de Wayland-socket hoort verdwenen te zijn. Controleer ook of de container nu start.

Je kan deze instellingen ook toevoegen via Preferences: Open User Settings (JSON) in het Command Palette:

VS Code-gebruikersinstellingen (settings.json)
{
"dev.containers.mountWaylandSocket": false,
// Optioneel, bij GPU-problemen:
"dev.containers.gpuAvailability": "none"
}

Voeg de regels toe aan je bestaande gebruikersinstellingen. Deze opties horen in de settings.json van VS Code, niet in .devcontainer/devcontainer.json.

Docker e-mailadres niet geverifieerd

De devcontainer start niet op omdat je Docker-account niet geverifieerd is. Je hoeft niet per se een Docker-account te hebben, maar als je er wel één hebt, moet je dat e-mailadres verifiëren.

Oplossing: log in op hub.docker.com en klik op de link in de verificatiemail die je van Docker kreeg.

Virtualisatie is niet ingeschakeld in BIOS

Je probeert de devcontainer te openen, maar krijgt een foutmelding dat virtualisatie niet ingeschakeld is in BIOS.

Oplossing: schakel virtualisatie in via de BIOS. Hoe dat moet, hangt af van je computer. Zoek op Google naar "enable virtualization in BIOS" en de naam van je computer of moederbord, of vraag hulp aan de lector.