Docker Volume: persistente opslag voor containers
Docker Volume is het mechanisme dat data loskoppelt van de levenscyclus van een container. Dit artikel legt uit hoe volumes werken, hoe je ze aanmaakt, beheert en opschoont, en waarom je ze boven bind mounts zou verkiezen.
Vereisten
- Docker Engine 20.10 of recenter (controleer met `docker --version`)
- Toegang tot de Docker daemon — lokaal of via SSH op een server
- Basisvertrouwdheid met `docker run` en de commandoregel
Wat een volume anders maakt dan de rest
Wanneer je een container start zonder volume, schrijft de container naar zijn eigen tijdelijke bestandssysteem. Stop je de container, dan blijft de data nog even liggen. Verwijder je de container, dan is alles weg.Een volume overleeft dat. Het wordt beheerd door de Docker-engine, opgeslagen op de host, en blijft bestaan zolang je het niet expliciet verwijdert. Een nieuwe container kan hetzelfde volume mounten en verdergaan waar de vorige stopte.
Dat maakt volumes geschikt voor databases, uploads, logbestanden — alles wat moet overleven. Een MySQL-container kan verwijderd worden, en zolang het volume er nog is, kan een verse container met hetzelfde volume de database exact hervatten.
Er is een alternatief: bind mounts koppelen een map van de host direct aan een pad in de container. Dat werkt, maar Docker heeft geen controle over wat er in die map gebeurt. Wijzig je bestanden buiten Docker om, dan kan de container daar vreemd op reageren. Volumes worden door Docker zelf beheerd — de engine houdt bij wat erin zit en waar het staat. Directe toegang tot de volumelocatie via het hostbesturingssysteem wordt niet ondersteund, en handmatig sleutelen aan die mappen leidt tot ongedefinieerd gedrag.
Zelf hosten klinkt prachtig, tot er iets omvalt op zondagavond half twaalf. Dan ben je geen klant die op de helpdesk wacht. Dan bén je de helpdesk.
Een volume aanmaken
Je kunt een volume op twee manieren laten ontstaan: expliciet of automatisch.Expliciet aanmaken geeft je controle over de naam en de configuratie:
```bash docker volume create mijn-data ```
Dit commando maakt een nieuw volume aan met de naam `mijn-data`. Laat je de naam weg, dan genereert Docker een willekeurige unieke naam — handig voor tests, maar lastig om later terug te vinden.
Het volume koppel je aan een container met de `-v`-optie:
```bash docker run -d -v mijn-data:/data alpine ```
Hier wordt het volume `mijn-data` gemount op het pad `/data` in de container. Alles wat de container naar `/data` schrijft, belandt in het volume.
De tweede manier is automatisch. Verwijs je bij `docker run` naar een volume dat nog niet bestaat, dan maakt Docker het zelf aan:
```bash docker run -d -v mijn-data:/data alpine ```
Let op: dit is hetzelfde commando als hierboven. Docker maakt het volume aan als het nog niet bestaat, en gebruikt het bestaande volume als het er al is. Voor snelle tests is dat handig. Voor productie is expliciet aanmaken beter — je hebt dan controle over de naamgeving en je vermijdt typefouten die stilletjes een nieuw, leeg volume creëren.
Volumes beheren
Het `docker volume`-commando biedt een reeks subcommando's. De belangrijkste:- `docker volume create` — maakt een nieuw volume aan
- `docker volume ls` — toont alle volumes
- `docker volume inspect` — geeft details over een volume in JSON-formaat
- `docker volume rm` — verwijdert een volume dat niet in gebruik is
- `docker volume prune` — verwijdert ongebruikte volumes
```bash docker volume ls ```
De output toont de naam, de driver en het mountpoint op de host. In omgevingen met veel volumes kun je filteren, bijvoorbeeld om alleen volumes te zien die niet in gebruik zijn:
```bash docker volume ls --filter dangling=true ```
Details over een specifiek volume haal je op met:
```bash docker volume inspect mijn-data ```
Dit retourneert een JSON-object met onder meer de mountlocatie op de host, de gebruikte driver en metadata. Die gegevens zijn nuttig voor debugging of voor scripts die de status van volumes moeten uitlezen.
Volumes delen tussen containers
Volumes zijn herbruikbaar. Meerdere containers kunnen hetzelfde volume mounten, zolang ze niet tegelijkertijd naar dezelfde bestanden schrijven. Dat maakt volumes geschikt voor scenario's waarin de ene service data produceert en de andere die data leest — logbestanden bijvoorbeeld.In Docker Compose definieer je volumes op top-niveau in het `docker-compose.yml`-bestand:
```yaml version: "3.9"
volumes: db-data:
services: db: image: mysql:8.4 volumes: - db-data:/var/lib/mysql ```
Het volume `db-data` wordt eenmaal gedeclareerd en kan door meerdere services gebruikt worden. Herstart je de stack, dan blijft de data behouden. Verwijder je de containers met `docker compose down`, dan blijft het volume bestaan — tenzij je `-v` toevoegt, en dan is het weg.
Volumes opschonen
Volumes nemen schijfruimte in, ook als de bijbehorende container al lang verwijderd is. Docker ruimt ze niet automatisch op.Het commando `docker volume prune` verwijdert volumes die niet aan een actieve container gekoppeld zijn:
```bash docker volume prune ```
Docker vraagt standaard om bevestiging. In scripts of geautomatiseerde omgevingen kun je die overslaan met de `-f`-flag:
```bash docker volume prune -f ```
Let op wat je verwijdert. Een volume dat niet aan een actieve container hangt, kan nog wel data bevatten die je later nodig hebt. `prune` vraagt niet of je zeker bent — het verwijdert gewoon.
Volume plugins en externe opslag
Lokale volumes werken prima op één host. Voor clusters of cloudomgevingen heeft Docker volume plugins, waarmee je volumes kunt koppelen aan externe opslagsystemen zoals Amazon EBS. Die plugins voegen replicatie, backup en schaalbaarheid toe, maar ze kosten ook: extra configuratie, extra afhankelijkheden, en een leverancier die je moet vertrouwen.Voor een enkele server of een kleine stack zijn lokale volumes voldoende. Begin daarmee, en schakel pas over naar een plugin wanneer je echt meerdere hosts moet synchroniseren.
Verificatie
Controleer of je volume correct werkt door een bestand te schrijven, de container te verwijderen en een nieuwe container met hetzelfde volume te starten:```bash docker run -d --name test-container -v mijn-data:/data alpine sleep 300 docker exec test-container sh -c "echo 'testdata' > /data/test.txt" docker rm -f test-container docker run --rm -v mijn-data:/data alpine cat /data/test.txt ```
De laatste regel zou `testdata` moeten tonen. Als dat zo is, werkt het volume correct en overleeft de data de levenscyclus van de container.
Veelgestelde problemen
Volume kan niet verwijderd worden`docker volume rm` weigert een volume dat nog door een actieve container wordt gebruikt. Stop en verwijder eerst de container:
```bash docker rm -f container-naam docker volume rm mijn-data ```
Data lijkt verdwenen na het herstarten van een container
Controleer of je het volume aan de juiste container hebt gekoppeld en of het pad klopt. Een typefout in het containerpad zorgt ervoor dat Docker een nieuw, leeg volume aanmaakt in plaats van het bestaande te gebruiken. `docker volume ls` toont of er onverwachte volumes zijn bijgekomen.
Schijfruimte raakt op door ongebruikte volumes
`docker volume ls --filter dangling=true` toont volumes die niet meer gebruikt worden. Verwijder ze met `docker volume prune`, maar controleer eerst of er geen data bij zit die je nog nodig hebt.