Docker-volumes versus bindingsmounts: bewaar containergegevens op de juiste manier

  1. Home
  2. Blog
  3. DevOps

DevOps

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.

9 min leestijd
Docker-volumes versus bind-mounts: bewaar containergegevens op de juiste manier

Belangrijkste punten

  • 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 -v verwijdert 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 /app mount, wordt alles wat de afbeelding daarin bevatte onzichtbaar. Een veelvoorkomend voorbeeld is dat node_modules vermist 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 :z of :Z label 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 -v wordt nonchalant uitgevoerd. Hiermee worden uw benoemde volumes verwijderd.
  • Relatieve paden gebruiken met -v. Formulieren zoals -v data:/x creë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

Werk met Stack Quora

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.

Blijf lezen

Meer handleidingen over testen, AI en moderne ontwikkeling

Genoten van dit artikel? Kies een onderwerp en ga direct naar onze nieuwste tutorials.

Kunstmatige intelligentie

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 →
DevOps

Omgevingsvariabelen 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 →
Softwareontwikkeling

API-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 →
Testautomatisering

Spotten 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 →
Softwaretesten

Codedekking 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 & SQL

DELETE 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 & SQL

SQL-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 →
Softwareontwikkeling

TypeScript-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 →
Softwareontwikkeling

Python *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 →
Softwareontwikkeling

Python 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 intelligentie

Wat 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 →
DevOps

Monitoring 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 →
DevOps

Docker-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 →
Testautomatisering

TDD 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 →
Softwareontwikkeling

Git 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 →
Softwareontwikkeling

Python 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 & SQL

SQL 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 →