Docker-volumes versus bindingsmounts: Containergegevens op de juiste manier bewaren
Verwijder een container en de gegevens ervan gaan mee, tenzij u deze op een veiligere plek bewaart. Leer het verschil tussen volumes, bindmounts en tmpfs, wanneer u ze moet gebruiken en hoe u een back-up kunt maken van wat belangrijk is.
- De beschrijfbare laag van een container wordt samen met de container verwijderd, dus belangrijke gegevens moeten worden gekoppeld.
- Benoemde volumes worden beheerd door Docker en zijn de gebruikelijke keuze voor databases en productiegegevens.
- Bind-mounts wijzen een hostmap toe, waardoor ze ideaal zijn voor live code tijdens de ontwikkeling.
docker compose down -vverwijdert volumes, dus gebruik het met zorg en bewaar geteste back-ups.
Je start een database in een container, voegt wat gegevens toe, verwijdert de container en start een nieuwe. De gegevens zijn verdwenen. Bijna iedereen leert deze les op de harde manier. Docker-volumes en bind-mounts zijn er om gegevens levend te houden tot na de levensduur van een container.
In deze handleiding wordt uitgelegd hoe ze allemaal werken en hoe u kunt kiezen. De opdrachten en bestanden hier zijn standaardvoorbeelden, gebaseerd op het gedocumenteerde gedrag van Docker, en we hebben ze niet uitgevoerd voor dit artikel, dus probeer ze eerst op wegwerpgegevens. Details kunnen verschillen tussen Docker-versies en op Docker Desktop. Als u nog niet bekend bent met containers, begin dan met onze Docker-tutorial voor beginners.
Waarom containergegevens verdwijnen
Een Docker-installatiekopie is gemaakt van alleen-lezen lagen. Wanneer een container start, voegt Docker er een dunne beschrijfbare laag bovenop toe, en eventuele wijzigingen worden daarheen doorgevoerd. Die laag overleeft een stop en herstart, maar wordt verwijderd wanneer de container wordt verwijderd.
docker run -d --name db -e POSTGRES_PASSWORD=devonly postgres:17
# ... create tables and add data ...
docker rm -f db
docker run -d --name db -e POSTGRES_PASSWORD=devonly postgres:17
# The data you added is not there
Dit is inherent aan het ontwerp, omdat u containers vrijelijk kunt vervangen. Het betekent wel dat alles wat u moet bewaren, buiten de container moet leven. Er zijn drie manieren om dat te doen:
| Typ | Opgeslagen in | Overleeft containerverwijdering? |
|---|---|---|
| Genoemd volume | Een gebied beheerd door Docker | Ja |
| Bind montage | Een hostpad dat u kiest | Ja |
| tmpfs-mount | Host-geheugen | Nee |
Docker-volumes versus bind-mounts naast elkaar
| Aspect | Genoemd volume | Bind montage |
|---|---|---|
| Beheerd door | Dokwerker | Jij |
| Locatie | Docker’s opslagruimte | Elk pad op de host |
| Afhankelijk van hostmappen? | Nee | Ja |
| Bewerken vanaf de host | Onhandig qua ontwerp | Gemakkelijk, wijzigingen verschijnen onmiddellijk |
| Leeg doel vooraf ingevuld vanuit afbeelding? | Ja | Nee, het hostpad verbergt het |
| Docker CLI-opdrachten | Ja, docker volume |
Nee |
| Stuurprogramma’s voor externe opslag | Ja | Nee |
| Beste voor | Databases, productiegegevens | Broncode in ontwikkeling |
Genoemde volumes
Een volume is opslag die door Docker wordt gemaakt en beheerd. Je noemt het bij naam, en het maakt je niet uit waar het fysiek leeft.
docker volume create pgdata
docker run -d --name db \
-e POSTGRES_PASSWORD=devonly \
-v pgdata:/var/lib/postgresql/data \
postgres:17
Nu bevinden de databasebestanden zich in pgdata. Verwijder de container en start een nieuwe met hetzelfde volume, en uw gegevens zullen er nog steeds zijn. Op Linux staan volumes meestal onder /var/lib/docker/volumes/, maar u moet deze bestanden niet rechtstreeks bewerken. Op Docker Desktop leven ze in een virtuele machine, niet in een normale map.
Het pad binnen de container is afhankelijk van de afbeelding, dus controleer de documentatie van de afbeelding. Mounten op het verkeerde pad is een klassieke fout: alles lijkt te werken, maar de gegevens worden nog steeds naar de containerlaag geschreven. Nieuwere hoofdversies van een afbeelding kunnen dit pad ook wijzigen, dus lees de release-opmerkingen voordat u een upgrade uitvoert.
Docker maakt automatisch een benoemd volume als dit niet bestaat. Een anoniem volume, gemaakt zonder naam, werkt ook, maar het krijgt een lange, willekeurige ID en is gemakkelijk uit het oog te verliezen. Geef uw volumes altijd een naam.
Bind houders
Een bind-mount wijst een specifiek hostpad rechtstreeks in de container toe. Beide partijen zien onmiddellijk dezelfde bestanden. Dit maakt het perfect voor ontwikkeling, omdat bewerkingen in uw editor van kracht worden in de actieve container zonder opnieuw te hoeven opbouwen:
docker run -d --name web \
-p 8080:80 \
-v "$(pwd)/site:/usr/share/nginx/html:ro" \
nginx:1.27
Bewerk een bestand in site/, ververs de browser en je zult de verandering zien. De :ro maakt de mount alleen-lezen in de container, wat een goede gewoonte is als de container daar niet hoeft te schrijven.
Bindmounts hebben een aantal nadelen:
- Ze verbinden je met de host. Het pad moet op elke machine bestaan, dus de instellingen zijn minder overdraagbaar.
- Ze verbergen de inhoud van de afbeelding. Als je over
/appmount, wordt alles wat de afbeelding daarin bevatte onzichtbaar. Een veelvoorkomend voorbeeld is datnode_modulesvermist wordt. - Ze stellen de host bloot. Een container met een beschrijfbare mount kan echte hostbestanden wijzigen of verwijderen. Monteer nooit gevoelige paden zoals
/of de Docker-socket, tenzij u het risico volledig begrijpt. - De prestaties kunnen variëren. Op Docker Desktop voor macOS en Windows overschrijdt het delen van bestanden de virtualisatiegrens en kan dit langzamer zijn dan op Linux.
tmpfs-mounts
Een tmpfs-mount leeft in het geheugen van de host en wordt nooit naar de containerlaag geschreven. Het verdwijnt wanneer de container stopt, dus het is geschikt voor tijdelijke bestanden, caches en kortstondige gevoelige gegevens:
docker run -d --tmpfs /app/cache:size=64m myapp:1.0
tmpfs is beschikbaar op Linux-hosts. Het kan ook databases versnellen in wegwerptestomgevingen, waar u zich geen zorgen hoeft te maken over het bewaren van de gegevens.
-v of –mount?
Beide vlaggen werken. --mount is langer, maar explicieter, en veel mensen geven er de voorkeur aan in scripts:
# Short form
docker run -v pgdata:/var/lib/postgresql/data postgres:17
# Explicit form
docker run --mount type=volume,source=pgdata,target=/var/lib/postgresql/data postgres:17
# Bind mount, read-only
docker run --mount type=bind,source="$(pwd)"/site,target=/usr/share/nginx/html,readonly nginx:1.27
Er is één betekenisvol verschil. Met -v wordt er een ontbrekend hostpad voor u aangemaakt als een lege map, die een typefout kan verbergen. Met --mount en een bindtype rapporteert Docker in plaats daarvan een fout. Ook bij -v bepaalt de linkerkant het type: een naam betekent een volume, en een pad betekent een bindingsmount. Dus -v data:/x en -v ./data:/x doen heel verschillende dingen.
Volumes in Docker Compose
De meeste echte projecten declareren opslag in een Compose-bestand. Deze gebruikt beide soorten, elk voor zijn juiste taak:
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- ./src:/app/src # bind mount: live code
depends_on:
- db
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: devonly
volumes:
- pgdata:/var/lib/postgresql/data # named volume: data
volumes:
pgdata:
Benoemde volumes moeten worden gedeclareerd in de sectie op het hoogste niveau volumes. Compose laat de werkelijke naam voorafgaan door de projectnaam. Bekijk onze Docker Compose-tutorial voor een volledige uitleg.
Tip: docker compose down behoudt benoemde volumes, maar docker compose down -v verwijdert deze, samen met uw gegevens. Wees vooral voorzichtig met scripts en shellgeschiedenis die -v bevatten.
Handige volumeopdrachten
| Commando | Wat het doet |
|---|---|
dockervolume ls |
Geeft volumes weer |
docker volume naam aanmaken |
Creëert een volume |
docker volume-inspectienaam |
Toont details, inclusief de locatie |
docker volume rm-naam |
Verwijdert een volume en de bijbehorende gegevens |
docker volume snoeien |
Verwijdert ongebruikte volumes |
docker-systeem df -v |
Toont schijfgebruik, inclusief volumes |
Controleer wat prune zal verwijderen voordat je het bevestigt, aangezien dit niet ongedaan kan worden gemaakt. Volumes die momenteel door geen enkele container worden gebruikt, kunnen nog steeds belangrijke gegevens bevatten.
Maak een back-up van een volume en herstel het
Er kan een back-up van een volume worden gemaakt door een kortstondige container uit te voeren die zowel het volume als een hostmap koppelt:
# Back up
docker run --rm \
-v pgdata:/data:ro \
-v "$(pwd)":/backup \
alpine tar czf /backup/pgdata.tar.gz -C /data .
# Restore into a new volume
docker volume create pgdata_restored
docker run --rm \
-v pgdata_restored:/data \
-v "$(pwd)":/backup \
alpine tar xzf /backup/pgdata.tar.gz -C /data
Voor een live database kan het kopiëren van dit soort bestanden een inconsistente status vastleggen. Stop eerst de container, of beter, gebruik de eigen tool van de database, zoals pg_dump voor PostgreSQL. En een back-up die u nog nooit hebt hersteld, is eigenlijk slechts hoop, dus test het herstel.
Bestandsrechten
“Toestemming geweigerd” is het meest voorkomende probleem met mounts. Bestanden behouden hun numerieke gebruikers- en groeps-ID’s op Linux, dus als een container wordt uitgevoerd als gebruiker 1000 en de hostmap toebehoort aan een andere gebruiker, mislukt het schrijven. Enkele manieren om dit op te lossen:
- Voer de container uit met een overeenkomende gebruiker:
docker run --user "$(id -u):$(id -g)" ... - Stel het juiste eigendom van uw image in, zoals beschreven in onze praktische tips voor Dockerfile.
- Geef de voorkeur aan benoemde volumes voor gegevens, omdat een nieuw volume het eigendom van de map van de afbeelding overneemt wanneer deze voor het eerst wordt gebruikt.
- Op systemen die SELinux gebruiken, hebben bindmounts mogelijk een
:zof:Zlabel nodig.
Vermijd de verleiding van chmod 777, zoals onze gids voor Linux-opdrachten uitlegt.
Welke moet je gebruiken?
| Situatie | Gebruik |
|---|---|
| Databasegegevens | Genoemd volume |
| Broncode live bewerken | Bind montage |
| Een configuratiebestand uit uw repository | Alleen-lezen bindingsmount |
| Gegevens delen tussen containers | Genoemd volume |
| Tijdelijke cache- of scratch-bestanden | tmpfs |
| Wegwerptestdatabase | tmpfs, of geen mount |
| Applicatiecode in productie | Bouw het in in de afbeelding |
Die laatste rij is belangrijk. Tijdens de productie hoort code thuis in de afbeelding, zodat wat u hebt getest, ook is wat u uitvoert. In clusters werkt dataopslag weer anders, via persistente volumes, die worden behandeld in de bredere Kubernetes-documentatie. In onze handleiding Docker vs Kubernetes wordt uitgelegd hoe deze twee zich verhouden.
Veel voorkomende fouten
- Aankoppelen op het verkeerde pad. De gegevens bevinden zich nog steeds in de containerlaag en verdwijnen later.
down -vwordt nonchalant uitgevoerd. Hiermee worden uw benoemde volumes verwijderd.- Relatieve paden gebruiken met
-v. Formulieren zoals-v data:/xcreëren een volume in plaats van een maptoewijzing. - Geheimen in beschrijfbare bindkoppelingen plaatsen. Mount ze alleen-lezen of gebruik een geheimenfunctie.
- Twee databasecontainers naar één volume richten. Dit kan de gegevens beschadigen.
- Er zijn geen back-ups. Een volume is geen back-up. Het leeft op dezelfde schijf.
Tot slot
De vuistregel is kort: benoemde volumes voor gegevens, bind-mounts voor code die je aan het bewerken bent, en tmpfs voor dingen die niet lang meegaan. Probeer het eens in een wegwerpdatabase. Maak een benoemd volume, voeg een rij toe, verwijder de container, start een nieuw volume en bevestig dat uw rij het heeft overleefd. Oefen vervolgens met het maken van een back-up en het herstellen voordat u er een nodig heeft.
Veelgestelde vragen
Wat is het verschil tussen een Docker-volume en een bind-mount?
Een volume wordt beheerd door Docker en opgeslagen in een eigen gebied. Een bind-mount brengt een specifiek hostpad dat u beheert, rechtstreeks in de container in kaart.
Verwijdert het stoppen van een container de gegevens ervan?
Nee. Gegevens in de beschrijfbare laag overleven een stop en een herstart. Het gaat verloren wanneer de container wordt verwijderd, tenzij deze wordt opgeslagen in een volume of bindmount.
Blijven Docker-volumes bestaan nadat Docker is samengesteld?
Ja, benoemde volumes blijven bestaan nadat Docker is samengesteld. Als u de vlag -v toevoegt, worden ze verwijderd, samen met alle gegevens die ze bevatten.
Waar worden Docker-volumes opgeslagen?
Op Linux, meestal onder /var/lib/docker/volumes. Op Docker Desktop leven ze in een virtuele machine. Gebruik docker volume-inspectie om de locatie te bekijken.
Kunnen meerdere containers een volume delen?
Ja, er kunnen meerdere containers op één volume staan. De applicatie moet gelijktijdige toegang veilig afhandelen, en databases mogen over het algemeen geen gegevensbestanden op deze manier delen.
Blijf leren
Hulp nodig met testen, WordPress of SEO?
We helpen teams betere software te leveren en hun sites te laten groeien. Vertel ons waar u mee bezig bent en wij stellen een duidelijke volgende stap voor.
Meer handleidingen over testen, AI en moderne ontwikkeling
Genoten van dit artikel? Kies een onderwerp en ga direct naar onze nieuwste tutorials.
AI-hallucinaties uitgelegd: waarom taalmodellen dingen verzinnen en hoe ze te verminderen
AI-hallucinaties uitgelegd: wat ze zijn, waarom taalmodellen ze produceren, veelvoorkomende typen, hoe je ze kunt verminderen met aarding en aanwijz…
Lees artikel →DevOpsOmgevingsvariabelen uitgelegd: .env-bestanden, geheimen en configuratie goed gedaan
Omgevingsvariabelen uitgelegd met Python-voorbeelden die we hebben uitgevoerd: ze lezen en instellen, waarom elke waarde een string is, .env-bestand…
Lees artikel →SoftwareontwikkelingAPI-snelheidsbeperking uitgelegd: algoritmen, headers en afhandeling van 429-fouten
API-snelheidsbeperking uitgelegd met een simulatie die we hebben uitgevoerd: token-bucket, vast venster, schuifvenster, 429 reacties, headers van sn…
Lees artikel →TestautomatiseringSpotten in Python: unittest.mock, patch en de fouten die tests doen liegen
Spotten in Python met unittest.mock, getest: Mock en return_value, side_effect, patchen waar een naam wordt gebruikt, spec en autospec, spotdatums e…
Lees artikel →SoftwaretestenCodedekking uitgelegd: lijn versus filiaaldekking en wat 100% werkelijk betekent
Codedekking uitgelegd met een echte dekking.py-run: dekking van lijnen, vertakkingen en condities, een rapport lezen, waarom 100% dekking nog steeds…
Lees artikel →Databases & SQLDELETE versus TRUNCATE versus DROP in SQL: verschillen, terugdraaien en wanneer elk te gebruiken
DELETE versus TRUNCATE versus DROP uitgelegd met geteste SQL: wat elk verwijdert, terugdraaien, triggers, identiteitsreset, snelheid en hoe PostgreS…
Lees artikel →Databases & SQLSQL-weergaven uitgelegd: creëer, gebruik en vermijd de valkuilen, met voorbeelden
SQL-weergaven uitgelegd met query's die we hebben uitgevoerd: een weergave maken, live resultaten, kolommen verbergen, prestaties, bijwerkbare en ge…
Lees artikel →SoftwareontwikkelingTypeScript-interface versus type: echte verschillen, getest met de compiler
TypeScript-interface versus type, gecontroleerd met de echte compiler: wat beide kunnen doen, wat slechts één kan doen, samenvoegen van declaraties,…
Lees artikel →SoftwareontwikkelingPython *args en **kwargs uitgelegd: flexibele functies met duidelijke voorbeelden
Python *args en **kwargs uitgelegd met code die we hebben uitgevoerd: in- en uitpakken, parametervolgorde, argumenten die alleen trefwoorden en posi…
Lees artikel →SoftwareontwikkelingPython Lambda-functies: syntaxis, echt gebruik en wanneer u ze niet moet gebruiken
Python lambda-functies uitgelegd met code die we hebben uitgevoerd: syntaxis, sorteren met sleutel, kaart en filter, sluitingen, de laat-bindende va…
Lees artikel →Kunstmatige intelligentieWat zijn AI-agenten? Hoe ze werken, met een eenvoudige agentloop die u kunt uitvoeren
Wat zijn AI-agenten? Een duidelijke gids voor de agentenlus, tools, geheugen en vangrails, met een kleine Python-lus die we hebben uitgevoerd, echte…
Lees artikel →DevOpsMonitoring versus waarneembaarheid: het echte verschil, met logboeken, statistieken en sporen
Monitoring versus waarneembaarheid uitgelegd: bekende en onbekende fouten, logboeken, statistieken en sporen, een walkthrough voor afrekenincidenten…
Lees artikel →DevOpsDocker-volumes versus bindingsmounts: bewaar containergegevens op de juiste manier
Docker-volumes versus bind-mounts uitgelegd: waarom containergegevens verdwijnen, benoemde volumes, bind-mounts, tmpfs, Compose-voorbeelden, back-up…
Lees artikel →TestautomatiseringTDD versus BDD: belangrijkste verschillen, één functie die op beide manieren is gebouwd en wanneer deze moet worden gebruikt
TDD versus BDD uitgelegd met één kortingsfunctie die in beide richtingen is gebouwd: rood-groen-refactor met code die we hebben uitgevoerd, gegeven-…
Lees artikel →SoftwareontwikkelingGit merge vs rebase: verschillen, voorbeelden en wanneer je wat gebruikt
Git merge vs rebase uitgelegd met echte logoutput, een vergelijkingstabel, de gouden regel van rebase en een veilige teamwerkwijze.
Lees artikel →SoftwareontwikkelingPython list comprehension: syntaxis, voorbeelden en wanneer je het vermijdt
Python list comprehension uitgelegd: syntaxis, filteren, if-else, geneste lussen, gemeten tijden en wanneer een gewone for-lus beter is.
Lees artikel →Databases & SQLSQL JOIN uitgelegd met voorbeelden (Inner, Left, Right, Full)
Begrijp SQL joins stap voor stap met voorbeeldtabellen en queries: INNER, LEFT, RIGHT, FULL, CROSS en SELF, plus veelgemaakte fouten en prestatietips.
Lees artikel →