Cursus
De opdracht docker pull is vrij vanzelfsprekend, maar onder de motorkap gebeurt er veel waar zelfs doorgewinterde experts niets van weten.
Elke developer zou dit moeten weten. Je pullt dagelijks images, maar als er iets stukgaat, is het lastig om te achterhalen waarom. Of de authenticatie faalt zonder duidelijke reden, je loopt tegen rate limits aan, of je eindigt in productie met de verkeerde imageversie. Elke fout kost je tijd om op te lossen, terwijl het eigenlijk niet had hoeven gebeuren.
Begrijpen hoe docker pull echt werkt, geeft je controle. Je weet waar images vandaan komen, hoe je ze ophaalt en hoe je problemen oplost voordat ze productie raken.
In dit artikel leg ik uit hoe image-pulling onder de motorkap werkt, welke rol registries spelen en hoe je images ophaalt in zowel lokale ontwikkel- als productieomgevingen.
Als je helemaal nieuw bent met Docker, raad ik je sterk aan om onze Introduction to Docker cursus te volgen, omdat die de basis behandelt die je nodig hebt om dit artikel te begrijpen.
Hoe docker pull onder de motorkap werkt
In deze sectie loop ik door de mechaniek van het commando docker pull en haal ik onduidelijkheid weg over wat er achter de schermen gebeurt.
Wat er gebeurt tijdens een docker pull
De basis-syntax is simpel:
docker pull python:3.14.2-bookworm

Dit commando praat standaard met Docker Hub, downloadt de Python-image en slaat die lokaal op je machine op. Maar er gebeurt meer dan je op het eerste gezicht ziet.
Zo verloopt het proces:
-
Je Docker-client stuurt een verzoek naar de registry (Docker Hub, tenzij je iets anders opgeeft)
-
De registry reageert met de image-manifest, die alle lagen opsomt waaruit de image is opgebouwd
- Je client downloadt vervolgens elke laag die hij nog niet heeft en slaat ze op in
/var/lib/dockerop Linux-systemen, en in door Docker Desktop beheerde mappen (bijvoorbeeld onder~Library/Containers/…op macOS enC:\Users\[Username]\AppData\...op Windows.)
De tag :latest is de Docker-standaard als je geen versie opgeeft. Voer docker pull python uit zonder tag en je krijgt python:latest. Dat klinkt handig, maar is riskant. De tag :latest betekent niet "de meest recente stabiele versie". Het betekent "wat de image-maintainer als latest heeft getagd". Dat kan tussen pulls veranderen en je builds stilletjes breken.
Imagelagen en content-addressable storage
Docker-images zijn opgebouwd uit lagen.
Elke laag vertegenwoordigt een wijziging ten opzichte van de vorige. Wanneer je een image bouwt, maakt elke instructie RUN, COPY of ADD in je Dockerfile een nieuwe laag. De uiteindelijke image is een stapel van deze lagen in de juiste volgorde samengevoegd.
Bekijk bijvoorbeeld de commando's achter de bovenstaande Python 3.14-image - daar gebeurt een hoop.
Content-addressable storage maakt dit mogelijk. Elke laag krijgt een unieke hash op basis van de inhoud. Als twee images dezelfde basislaag delen (zoals ubuntu:24.04), slaat Docker die laag maar één keer op. Wanneer je een nieuwe image pullt die dezelfde basis gebruikt, slaat Docker het downloaden daarvan over.
Dat scheelt bandbreedte en opslag. Pull tien Python-images met verschillende tags en Docker hergebruikt de gemeenschappelijke lagen in al die images. Je downloadt alleen wat echt anders is.
docker pull vs docker image pull
Beide commando's zijn functioneel identiek. Ze halen images op uit registries en slaan ze lokaal op.
Het verschil is organisatorisch. Docker introduceerde de commando-groep docker image als onderdeel van een herstructurering van de CLI om commando's logischer te maken. In plaats van docker pull, docker rmi en docker images verspreid te hebben, zijn image-gerelateerde commando's gegroepeerd onder docker image pull, docker image rm en docker image ls.
Gebruik wat je prettig vindt. docker pull is korter en komt vaker voor in documentatie. docker image pull is explicieter en past beter in scripts waar duidelijkheid belangrijk is. Kies één stijl en hanteer die consequent binnen je team.
Docker-imagereferenties uitgelegd
Een imagereferentie heeft maximaal vijf delen: HOST/NAMESPACE/REPOSITORY:TAG@DIGEST.
Dit betekent elk onderdeel:
-
HOST: Het registry-adres (bijv.
docker.io,gcr.io,quay.io). Laat je dit weg, dan gebruikt Docker standaard Docker Hub. -
NAMESPACE: Meestal je gebruikersnaam of organisatie (bijv.
libraryvoor officiële images, ofmycompanyvoor private images). -
REPOSITORY: De daadwerkelijke imagenaam (bijv.
python,nginx,redis). -
TAG: De versie-identificatie (bijv.
3.14.2-bookworm, latest). Standaard is:latestals je deze overslaat. -
DIGEST: Een SHA256-hash van de image-manifest (bijv.
@sha256:abc123...). Dit is immutabel - tags kunnen veranderen, digests niet.
De meeste pulls zien er zo uit:
docker pull python:3.14.2-bookworm
Dit wordt achter de schermen uitgebreid naar docker.io/library/python:3.14.2-bookworm.
Voor private registries heb je de volledige referentie nodig:
docker pull myregistry.example.com/myteam/myimage
Nauwkeurige referenties gebruiken (specifieke tags of digests) maakt je deployments reproduceerbaar. Pull python:3.14.2-bookworm vandaag en volgende maand, en je krijgt dezelfde image. Pull python:latest twee keer, en de kans is groot dat je niet dezelfde krijgt.
Docker-registries en waar images vandaan komen
Registries zijn waar Docker images opslaat en distribueert - ze zijn de bron voor elk docker pull commando dat je uitvoert.
Docker Hub als standaardregistry
Docker Hub is de standaardregistry voor alle docker pull commando's, tenzij je iets anders opgeeft.
Voer docker pull python:3.14.2-bookworm uit, en Docker zet dit automatisch om naar docker.io/library/python:3.14.2-bookworm. Voor publieke images hoef je niet in te loggen - Docker Hub levert ze anoniem, wel met rate limits voor niet-aangemelde gebruikers.
Er zijn twee soorten images op Docker Hub: officiële images en community-images.
-
Officiële images komen van geverifieerde uitgevers en worden beheerd door Docker of de softwareleveranciers zelf. Ze staan onder de namespace
library(die Docker voor je verbergt). Als jepython,nginxofredispullt, krijg je officiële images die Docker's best practices voor veiligheid en regelmatige updates volgen. -
Community-images is al het andere. Iedereen kan een image publiceren op Docker Hub onder zijn gebruikersnaam of organisatie. Pull je
johndoe/python-custom, dan vertrouw je erop dat johndoe die image goed onderhoudt. Sommige community-images zijn uitstekend en goed onderhouden. Andere zijn al jaren niet bijgewerkt en bevatten bekende kwetsbaarheden.
Vertrouwen is hier belangrijk. Officiële images krijgen regelmatig beveiligingspatches en hebben duidelijke documentatie. Maar bij community-images moet je zelf verifiëren wie ze onderhoudt en of ze veilig zijn om te gebruiken.
Private en aangepaste registries
De meeste bedrijven willen hun containerimages niet op de publieke Docker Hub hebben staan.
Private registries zijn dan de oplossing. Jij bepaalt wie images mag pullen, je beheert retentiebeleid en je houdt propriëtaire code binnen je infrastructuur. Dit is belangrijk voor compliance, security en toegangsbeheer tussen teams.
Veelgebruikte oplossingen voor private registries zijn onder andere:
- Harbor: Open-source registry met ingebouwde security-scans en toegangscontrole
- JFrog Artifactory: Enterprise-oplossing die Docker-images én andere artifacttypen afhandelt
- Cloud-registries: AWS ECR, Google Container Registry (GCR), Azure Container Registry (ACR)
Uiteraard veranderen imagereferenties wanneer je een aangepaste registry gebruikt. In plaats van python:3.14.2-bookworm, moet je nu het volledige pad opgeven:
docker pull myregistry.company.com/team/python:3.14.2-bookworm
De registry-hostnaam komt eerst, dan je namespace (meestal een team- of projectnaam), daarna de repository en de tag. Docker kiest niet voor Docker Hub wanneer hij een aangepaste hostnaam ziet - hij gaat direct naar je private registry.
Authenticatie, rate limits en toegangsbeheer
Authenticatie is nodig voor zowel pushen als pullen van images, en wordt vooral belangrijk wanneer je tegen rate limits aanloopt of private registries gebruikt.
Inloggen en credentials beheren
Je kunt het commando docker login gebruiken om je te authenticeren bij een registry:
docker login
Dit vraagt om je Docker Hub-gebruikersnaam en -wachtwoord. Voor private registries geef je gewoon de hostnaam op:
docker login myregistry.company.com

Docker slaat je credentials lokaal op na het inloggen. Op Linux staan ze in ~/.docker/config.json. Op macOS gebruikt Docker de systeem-sleutelhangertoegang voor betere beveiliging.
Het probleem is dat het configbestand credentials standaard in base64 opslaat, wat geen versleuteling is. Iedereen met toegang tot je thuismap kan ze decoderen. Om dit te beperken kun je in plaats daarvan een credential helper gebruiken - Docker ondersteunt native OS-keychains die wachtwoorden veilig opslaan.
Hier zijn een paar best practices voor credentialbeheer:
-
Gebruik credential helpers (docker-credential-osxkeychain, docker-credential-wincred)
-
Commit
config.jsonnooit naar versiebeheer -
Gebruik toegangstokens in plaats van wachtwoorden waar mogelijk
-
Roteer credentials regelmatig, vooral voor gedeelde accounts
Docker Hub-rate limits
Docker Hub beperkt hoeveel images je binnen een tijdsvenster kunt pullen.
Anonieme gebruikers (geen login) krijgen 100 pulls per zes uur per IP-adres. Aangemelde gratis gebruikers krijgen 200 pulls per zes uur. Betaalde abonnementen hebben hogere limieten of onbeperkte pulls, afhankelijk van het niveau.
Deze limieten zijn relevant als je CI/CD-pijplijnen draait, vaak images pullt tijdens ontwikkeling, of werkt op gedeelde infrastructuur waar meerdere gebruikers hetzelfde IP delen. Als je de limiet raakt, mislukken je pulls totdat het venster reset.
Je kunt je huidige rate-limitstatus controleren:
TOKEN=$(curl "<https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull>" | jq -r .token)
curl --head -H "Authorization: Bearer $TOKEN" <https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest>

Hier zijn enkele manieren om je rate limit te verhogen (voor de meeste developers geen probleem):
- Authenticeer je pulls: Log in voor hogere limieten, zelfs met een gratis account
- Gebruik registry-mirrors: Zet een pull-through cache op die images lokaal opslaat
- Schakel over naar private registries: Host je eigen registry om Docker Hub-limieten volledig te vermijden
- Cache images lokaal: Pull één keer, hergebruik vaak in plaats van steeds opnieuw te pullen
De makkelijkste oplossing is gewoon inloggen. Dat verdubbelt je rate limit meteen.
Geavanceerde opties voor images pullen
Deze geavanceerde opties geven je precisie en controle, precies wat je nodig hebt in productieomgevingen.
Images pullen op digest
Digests zijn immutabele identifiers op basis van de content-hash van de image.
Tags kunnen veranderen. Iemand pusht een nieuwe image met dezelfde tag en ineens verwijst python:3.14.2-bookworm naar andere content dan gisteren. Digests kunnen niet wijzigen - het zijn SHA256-hashes van de image-manifest. Dezelfde digest betekent altijd exact dezelfde image.
Pullen op digest doe je zo:
docker pull python@sha256:6d58c1a9444bc2664f0fa20c43a592fcdb2698eb9a9c32257516538a2746c19a

docker pull --platform linux/amd64 python:3.14.2-bookworm
Dit is vooral belangrijk in CI/CD en productie. Je test tegen een specifieke image, je deployt exact die image. Geen verrassingen, geen drift tussen omgevingen. Als je deployment afhangt van een specifieke versie, gebruik de digest - niet de tag.
Multi-architectuur image-pulls
Multi-arch images bundelen versies voor verschillende CPU-architecturen in één imagereferentie.
Pull python:3.14.2-bookworm, en Docker kiest automatisch de juiste versie voor je systeem - amd64 voor x86-machines, arm64 voor Apple Silicon of ARM-servers. De registry levert de juiste architectuur zonder dat jij iets hoeft te doen.
Maar soms heb je een specifieke architectuur nodig. Gebruik de vlag --platform:
docker pull --platform linux/amd64 python:3.14.2-bookworm

Dit is handig wanneer je ontwikkelt op Apple Silicon maar de amd64-versie moet testen die in productie draait, of wanneer je images bouwt voor een andere architectuur dan je buildmachine.
Meerdere tags pullen
De vlag --all-tags pullt alle tags voor een repository:
docker pull --all-tags python
Dit downloadt alle Python-tags - tientallen versies, varianten en architecturen. Je eindigt met gigabytes aan images.
Gebruik dit niet tenzij je het echt nodig hebt. Bandbreedte kost geld, opslag loopt snel vol, en je hebt waarschijnlijk niet elke Python-versie ooit uitgebracht nodig. Pull specifieke tags die je daadwerkelijk gebruikt.
Een pull annuleren
Druk op Ctrl+C of CMD+C om een lopende pull te annuleren.
Docker stopt met het downloaden van nieuwe lagen maar houdt de lagen die al klaar zijn. De volgende keer dat je dezelfde image pullt, gaat hij verder waar hij gebleven was in plaats van opnieuw te beginnen.
Dit is handig als je per ongeluk de verkeerde image pullt, wanneer een pull te lang duurt op een trage verbinding, of wanneer je beseft dat je die image nu niet nodig hebt. Annuleer, corrigeer je commando en pull opnieuw zonder het al verrichte werk te verspillen.
Prestatie-overwegingen bij docker pull
Netwerken in de echte wereld hebben beperkingen, zoals bandbreedtelimieten, proxies en trage verbindingen. Die kunnen pulls onnodig lang laten duren, dus laat ik je zien wat je eraan kunt doen.
Pull-prestaties optimaliseren
Docker downloadt imagelagen standaard gelijktijdig.
In plaats van lagen één voor één te pullen, opent Docker meerdere verbindingen en downloadt het meerdere lagen tegelijk. Dit versnelt pulls op snelle verbindingen, maar op trage netwerken waar bandbreedte de bottleneck is, merk je weinig verschil.
Twee veelvoorkomende strategieën helpen nog meer:
- Caching houdt gepulde images lokaal opgeslagen. Pull een image één keer, gebruik die honderden keren. Docker controleert of je de lagen al hebt voordat er iets wordt gedownload. Als de image niet is veranderd, is de pull direct klaar.
- Preloaden van images betekent ze pullen tijdens daluren of als onderdeel van je deploymentproces. CI/CD-systemen cachen vaak basisimages op buildagents zodat developers niet bij elke build op pulls hoeven te wachten. Productieservers kunnen tijdens deployment hun cache opwarmen om te vermijden dat ze images moeten pullen wanneer het verkeer binnenkomt.
Images pullen achter proxies
Bedrijfsnetwerken leiden verkeer via proxies voor beveiliging, monitoring en toegangscontrole.
Docker moet van deze proxies weten om images te kunnen pullen. Zonder proxyconfiguratie mislukken pulls met time-outs of DNS-fouten omdat Docker probeert registries direct te bereiken in plaats van via de proxy.
Je configureert proxies op twee niveaus: de Docker-client en de Docker-daemon. De client (je docker commando) gebruikt automatisch de HTTP-proxy-instellingen van je systeem. De daemon heeft expliciete configuratie nodig in /etc/docker/daemon.json of via systemd-servicebestanden.
Veelvoorkomende pull-problemen oplossen
Hier is een praktische checklist voor wanneer pulls falen - want dat gebeurt, en je moet weten wat je eerst controleert.
Veelvoorkomende fouten en hoe je ze diagnosticeert
Authenticatiefouten verschijnen als "unauthorized" of "access denied"-fouten.
Controleer of je bent ingelogd met docker login. Als dat zo is, zijn je credentials mogelijk verlopen of onjuist. Log uit met docker logout en log opnieuw in. Voor private registries, zorg dat je de juiste hostnaam gebruikt in je login-commando.
Ontbrekende tags geven "manifest unknown" of "not found"-fouten.
De tag bestaat niet. Controleer de tagnaam dubbel; typefouten komen vaak voor. Kijk in de webinterface van de registry welke tags daadwerkelijk bestaan. Onthoud dat tags kunnen zijn verwijderd, dus iets dat gisteren werkte, werkt vandaag mogelijk niet meer.
Netwerktime-outs ontstaan wanneer Docker de registry niet kan bereiken.
Controleer eerst je internetverbinding. Controleer dan of je de registry direct kunt bereiken - voer ping registry-1.docker.io of curl -I <https://registry-1.docker.io> uit. Als je achter een proxy zit, zorg dat Docker daarvan op de hoogte is. Als de registry privé is, controleer firewallregels en VPN-verbindingen.
Rechtenproblemen verschijnen als "denied"-fouten, zelfs wanneer je geauthenticeerd bent.
Je bent ingelogd, maar je account heeft geen pull-toegang tot deze specifieke repository. Neem contact op met de eigenaar van de repository of je registry-beheerder om toegang te krijgen. Voor Docker Hub betekent dit meestal dat de image privé is en jij niet op de toegangs lijst staat.
DNS- en netwerkresolutieproblemen
DNS-fouten voorkomen dat Docker de registry-server kan vinden.
Je ziet fouten zoals "no such host" of "temporary failure in name resolution". Wat er echt gebeurt, is dat Docker de hostnaam van de registry niet naar een IP-adres kan vertalen en dus geen verbinding kan maken.
Om dit op te lossen, controleer de DNS-resolutie met nslookup registry-1.docker.io of dig registry-1.docker.io. Als deze commando's falen, is je DNS-server onbereikbaar of verkeerd geconfigureerd. Probeer tijdelijk over te schakelen naar een publieke DNS-server zoals 8.8.8.8 om te zien of dat het oplost.
Op bedrijfsnetwerken lost de DNS-server mogelijk alleen interne hostnamen op. Zorg dat de hostnaam van je private registry in de DNS-server staat, of voeg hem toe aan /etc/hosts als tijdelijke oplossing totdat DNS is gefikst.
docker pull in georchestreerde en lokale workflows
Dan nu het leuke deel - hoe het docker pull-commando werkt in scenario's die je op je werk mag verwachten.
Image-pulls in Kubernetes
Kubernetes pullt images automatisch wanneer je pods uitrolt.
Je definieert een container in je pod-spec met een imagereferentie, en Kubernetes regelt de pull voor je. De kubelet op elke node controleert of de image lokaal bestaat. Zo niet, dan pullt hij uit de registry voordat de container wordt gestart.
Pull policies bepalen wanneer Kubernetes images pullt:
-
Always: Pull de image elke keer, ook als die lokaal bestaat -
IfNotPresent: Pull alleen als de image nog niet op de node staat (standaard voor getagde images) -
Never: Nooit pullen, falen als de image niet al lokaal staat
Stel de policy in je pod-spec in met imagePullPolicy. Gebruik Always voor :latest tags in ontwikkeling om updates te krijgen. Gebruik IfNotPresent voor specifieke tags in productie om onnodige pulls te vermijden.
Met imagePullSecrets geef je Kubernetes toegang tot private registries. Je kunt een secret maken met je registry-credentials en die refereren in je pod-spec. Zonder dat kan Kubernetes alleen publieke images pullen.
Docker Compose en lokale ontwikkeling
Compose automatiseert pulls wanneer je applicaties met meerdere services start.
Voer docker compose up uit en Compose controleert de image van elke service. Als een image ontbreekt, pullt Compose die voordat de containers starten. Je hoeft niet voor elke service handmatig docker pull uit te voeren; Compose regelt dat voor je.
Dit werkt uitstekend voor ontwikkeling. Je definieert je services in docker-compose.yml, voert één commando uit en Compose pullt alles wat je nodig hebt. De eerste up duurt langer terwijl images downloaden, maar volgende runs zijn direct als de images niet zijn veranderd.
docker compose vs docker compose pull
Dit zijn twee verschillende commando's die verschillende dingen doen.
docker compose up start je services. Het pullt ontbrekende images automatisch, maar alleen als ze niet lokaal bestaan. Als je python:3.14.2-bookworm al op je machine hebt, gebruikt Compose die zonder op updates te controleren.
docker compose pull pullt expliciet alle images die in je compose-bestand staan, of ze nu lokaal bestaan of niet. Dit controleert op updates in registries en downloadt nieuwere versies indien beschikbaar.
Wanneer heb je docker compose pull nodig?
-
Je gebruikt
:latesttags en wilt de nieuwste versie. Voer eerstdocker compose pulluit om updates te krijgen, en daarnadocker compose upom met verse images te starten. -
Je bent aan het debuggen en vermoedt dat je lokale image verouderd of corrupt is. Pull verse kopieën met
docker compose pullen start daarna opnieuw. -
Je wilt images preloaden voordat je services daadwerkelijk start. Voer
docker compose pulluit tijdens deployment om images te cachen; vervolgens draaitdocker compose updirect zonder te wachten op downloads.
Het kernverschil is dat up alleen pullt wat ontbreekt, en pull alles bijwerkt, ongeacht wat je al hebt.
Conclusie
Het commando docker pull lijkt simpel, maar onder de oppervlakte gebeurt veel en er is veel wat je kunt afstellen. Dit zijn enkele best practices om te onthouden.
Gebruik expliciete tags of digests in plaats van :latest. Authenticeer je pulls om rate limits te vermijden. Wees zuinig met bandbreedte en opslag bij het pullen van images, vooral in CI/CD-pijplijnen waar je constant pullt.
Behandel image-pulls als onderdeel van je security-pijplijn. Elke pull is een potentieel aanvalsoppervlak als je onbetrouwbare bronnen gebruikt of verouderde images met bekende kwetsbaarheden. Verifieer bronnen, scan op issues en houd basisimages up-to-date.
Docker-registries en tooling veranderen regelmatig. Blijf op de hoogte van updates van je registry-provider om verrassingen te voorkomen die je workflow breken.
Als je klaar bent om je Docker- en containerization-skills naar een professioneel niveau te tillen, bekijk dan onze Intermediate Docker cursus of kies voor onze volledige Containerization and Virtualization with Docker and Kubernetes track.
docker pull FAQ's
Wat doet docker pull?
docker pull downloadt containerimages van registries zoals Docker Hub naar je lokale machine. Het haalt de imagelagen op die je nog niet hebt en slaat ze lokaal op, zodat je containers van die image kunt draaien. Zonder eerst images te pullen, kun je geen containers starten tenzij de images al op je systeem staan.
Hoe vermijd ik Docker Hub-rate limits?
Log in met docker login om je rate limit te verdubbelen van 100 naar 200 pulls per zes uur. Voor teams die vaak tegen limieten aanlopen: gebruik een private registry of zet een pull-through cache op die images lokaal opslaat. De makkelijkste oplossing is authenticeren - zelfs een gratis Docker Hub-account maakt een groot verschil.
Wat is het verschil tussen docker pull en docker image pull?
Het zijn functioneel identieke commando's die exact hetzelfde doen. Docker introduceerde docker image pull als onderdeel van een reorganisatie van de CLI om gerelateerde commando's te groeperen. Gebruik wat je wilt - docker pull is korter en gangbaarder, terwijl docker image pull explicieter is in scripts.
Moet ik in productie imagetags of digests gebruiken?
Gebruik digests in productie voor gegarandeerde immutabiliteit. Tags zoals python:3.14.2-bookworm kunnen veranderen als iemand een nieuwe image pusht met dezelfde tag, maar digests zijn SHA256-hashes die nooit veranderen. Pull op digest met docker pull python@sha256:abc123… om zeker te zijn dat je elke keer exact dezelfde image krijgt.
Waarom faalt docker pull met "manifest unknown"-fouten?
De tag die je probeert te pullen bestaat niet in de registry. Controleer de tagnaam op typefouten en verifieer via de webinterface van de registry of de tag bestaat. Tags kunnen ook worden verwijderd, dus iets dat eerder werkte, is mogelijk niet meer beschikbaar.

