Les 3 van 5
Je werk bewaren
Bewaar je labwerk buiten de container met een bind mount (-v) of een volume, en vermijd de valkuilen met rechten en Windows-paden.
📑 Op deze pagina
🎯 Na deze les kun je
- uitleggen waarom je werk verdwijnt als een container stopt
- een map van je computer aan een lab-container koppelen met -v
- het verschil tussen een bind mount en een volume uitleggen
- paden goed schrijven in bash, PowerShell, cmd en Git Bash
In de vorige les zag je het: met --rm wordt de container na exit opgeruimd, en je werk verdwijnt mee. Ook zonder --rm is werken in een container onhandig: je bestanden zitten verstopt in Docker en je kunt ze niet openen in je eigen editor. De oplossing is een map van je eigen computer koppelen aan een map in de container. Wat je daar opslaat, staat gewoon op je eigen schijf, en is er morgen nog.
Waarom je werk verdwijnt
Een container is een tijdelijke laag bovenop een image. Het image zelf verandert nooit. Alles wat je in de container wijzigt, komt in die tijdelijke laag, en die verdwijnt als de container wordt verwijderd. Dat is juist een sterk punt van containers: je begint altijd met dezelfde, schone omgeving. Maar je eigen werk wil je bewaren.
Docker kent daar twee manieren voor:
- een bind mount: een bestaande map van je computer verschijnt in de container;
- een volume: een opslagplek die Docker zelf beheert, met een naam.
Voor de labs is een bind mount het handigst: je ziet je bestanden in je eigen verkenner en editor.
Een bind mount met -v
De optie heet -v (volume) en heeft de vorm:
-v <map op je computer>:<map in de container>
De lesmappen staan in de container in /home/student/lessen. Koppel daar een map van je computer aan.
Linux en macOS (en de Ubuntu-terminal van WSL):
mkdir -p ~/beetje-werk/python
docker run -it --rm --user "$(id -u):$(id -g)" \
-v "$HOME/beetje-werk/python:/home/student/lessen" \
-e BEETJE_COURSE=python -e BEETJE_LESSON=2 \
registry.wizg.it/webhosting/beetjecoderen-web:lab-python-latest
Nieuw zijn twee regels:
-v "$HOME/beetje-werk/python:/home/student/lessen"koppelt je map~/beetje-werk/pythonaan~/lessenin de container. Bij het opstarten zet het image de startbestanden daarin klaar, en alles wat je maakt komt op je eigen schijf.--user "$(id -u):$(id -g)"laat de container draaien met jouw gebruikers- en groepsnummer. Waarom dat nodig is, lees je hieronder bij de valkuilen.
Maak voor elke cursus een eigen map (beetje-werk/python, beetje-werk/c-cpp, …). De lesmappen heten in elke cursus 01, 02, enzovoort, dus anders lopen ze door elkaar.
Typ nu exit en start hetzelfde commando opnieuw: je bestanden zijn er nog. Het image overschrijft bij het opstarten nooit bestanden die al bestaan; het vult alleen aan wat ontbreekt.
Windows: paden schrijven
Op Windows hangt het pad af van de terminal die je gebruikt. Dit gaat het vaakst mis.
PowerShell:
mkdir $HOME\beetje-werk\python
docker run -it --rm -v "${HOME}\beetje-werk\python:/home/student/lessen" -e BEETJE_COURSE=python -e BEETJE_LESSON=2 registry.wizg.it/webhosting/beetjecoderen-web:lab-python-latest
Opdrachtprompt (cmd):
mkdir %USERPROFILE%\beetje-werk\python
docker run -it --rm -v "%USERPROFILE%\beetje-werk\python:/home/student/lessen" -e BEETJE_COURSE=python -e BEETJE_LESSON=2 registry.wizg.it/webhosting/beetjecoderen-web:lab-python-latest
Let op deze punten:
- Links Windows-stijl, rechts Linux-stijl. Het deel vóór de dubbele punt is een Windows-pad (met
\en een schijfletter mag), het deel erna is een pad in de Linux-container en gebruikt altijd/. - Aanhalingstekens om het hele
-v-argument, zeker als er een spatie in je pad zit (C:\Users\Sanne de Vries\…). --userlaat je op Windows en macOS weg in PowerShell en cmd: daar bestaatidniet, en Docker Desktop regelt de rechten op gekoppelde mappen zelf.- Git Bash zet paden die met
/beginnen stiekem om naar Windows-paden, waardoor/home/student/lesseniets alsC:/Program Files/Git/home/student/lessenwordt. ZetMSYS_NO_PATHCONV=1voor het commando, of gebruik PowerShell. Krijg je in Git Bash de fout the input device is not a TTY, zet danwinptyvoordocker.
De snelste optie op Windows: werk vanuit WSL. Open de Ubuntu-terminal en gebruik het Linux-commando van hierboven, met een map in je Linux-thuismap (~/beetje-werk/…). Bestanden onder /mnt/c/… (je Windows-schijf) werken ook, maar zijn vanuit een container merkbaar trager. Je Linux-bestanden open je in Windows via \\wsl$\Ubuntu\home\<naam> in de Verkenner, of met VS Code en de WSL-extensie.
Valkuil: rechten op Linux
De lab-images draaien niet als root, maar als een gewone gebruiker met nummer 20000. Op Linux is een gekoppelde map gewoon een map op je schijf, met de rechten die hij daar heeft. Die map is van jou (meestal nummer 1000), dus gebruiker 20000 mag er niet in schrijven. Zonder --user krijg je dan fouten als:
cp: cannot create regular file '/home/student/lessen/02/OPDRACHT.md': Permission denied
Met --user "$(id -u):$(id -g)" draait de container met jouw nummer, en mag hij wel schrijven. De lab-images zijn daarop gemaakt: de thuismap in de container is voor elke gebruiker beschrijfbaar. Je prompt blijft student@lab, dat is alleen een vaste naam.
Nog twee dingen die op Linux misgaan:
- De map bestaat nog niet. Dan maakt Docker hem zelf aan, maar als
root, en kan de container er niet in schrijven. Maak de map daarom eerst zelf metmkdir -p. - SELinux (Fedora, RHEL): krijg je Permission denied terwijl de rechten kloppen, zet dan
:zachter het-v-argument:-v "$HOME/beetje-werk/python:/home/student/lessen:z".
Een volume: opslag die Docker beheert
Wil je je bestanden niet op een zelfgekozen plek, maar wel bewaren? Dan kan een volume: een opslagplek met een naam die Docker zelf beheert. Je schrijft een naam in plaats van een pad:
docker run -it --rm -v beetje-python:/home/student -e BEETJE_COURSE=python -e BEETJE_LESSON=2 registry.wizg.it/webhosting/beetjecoderen-web:lab-python-latest
Docker maakt het volume beetje-python de eerste keer zelf aan. Hier koppel je het aan de hele thuismap /home/student, niet aan ~/lessen. Dat heeft een reden: een nieuw, leeg volume neemt de inhoud en de rechten over van de map in het image waar je het aan koppelt. De thuismap is in het image voor iedereen beschrijfbaar, maar de map ~/lessen bestaat in het image nog niet. Een volume op ~/lessen zou dus van root worden, en dan kan de container er niet in schrijven.
Handige commando's:
docker volume ls # alle volumes
docker volume inspect beetje-python
docker volume rm beetje-python # verwijderen: je werk is dan weg!
Het nadeel: je bestanden zitten in Docker, niet in een map die je makkelijk opent. Bind mounts zijn voor de labs daarom de eerste keus. En pas op: docker system prune --volumes en docker volume prune verwijderen volumes die op dat moment niet in gebruik zijn, en daarmee je werk (meer daarover in les 4).
Veelgemaakte fouten
-vvergeten en uren werk kwijt naexit. Zet het commando met-vin een notitie of een klein script, dan gebruik je altijd hetzelfde.- Een relatief pad links zoals
-v beetje-werk:/home/student/lessen. Zonder/,~,$HOMEof schijfletter ziet Dockerbeetje-werkals de naam van een volume en niet als map. Gebruik een volledig pad. - Rechts een Windows-pad zoals
C:\home\student. Het pad in de container is altijd een Linux-pad. - Dezelfde map voor twee cursussen. Les
02van de ene cursus komt dan in dezelfde map als les02van de andere.
Oefenen
- Maak een map
beetje-werk/<cursus>en start een lab met-v. Open de map daarna in je verkenner of editor. Staan de lesmappen erin? - Maak in de container een bestand
~/lessen/02/notitie.txt, typexit, en open het bestand op je eigen computer. - (Linux) Start dezelfde container één keer zonder
--user. Welke fout krijg je? Leg uit waarom.
Samenvatting
- Wat je in een container maakt, verdwijnt met de container. Koppel een map om het te bewaren.
- Bind mount:
-v "<pad op je computer>:/home/student/lessen", met een volledig pad links en een Linux-pad rechts. - Linux en macOS: voeg
--user "$(id -u):$(id -g)"toe en maak de map eerst zelf aan. - Windows: let op aanhalingstekens,
${HOME}in PowerShell,%USERPROFILE%in cmd enMSYS_NO_PATHCONV=1in Git Bash; vanuit WSL werken is het snelst. - Een volume (
-v beetje-python:/home/student) bewaart je werk in Docker zelf;docker volume rmenprune --volumesgooien het weg.
📝 Quiz: je werk bewaren
Log in om de quiz te maken. Met een gratis account kijk je je antwoorden na, bewaar je je voortgang en verdien je XP. De les zelf blijft gewoon gratis te lezen.