Last chance! 50% off DataCamp Premium
Sale ends in
Autonome AI-codingagents zijn krachtig. Ze navigeren door je filesystem, voeren shell-commando‘s uit, maken commits en wijzigen bestanden, allemaal zonder dat jij een regel code typt. Die kracht roept echter een terechte vraag op: wat als er iets misgaat? Wat als de agent een configbestand aanpast dat hij niet mag aanraken, of een package installeert die botst met je systeem?
Het antwoord waar de meeste op productie gerichte developers op uitkomen is Docker, en het is hetzelfde antwoord waar ik zelf steeds op terugkwam na een sessie waarin Claude Code behulpzaam het .env-bestand van mijn project had “opgeruimd” omdat het ongebruikt leek. (Het was niet ongebruikt.)
Containers geven je een harde scheiding tussen de agent en je hostmachine, en juist die grens zorgt ervoor dat onbeheerde agent-runs veilig voelen in plaats van zenuwslopend.
In deze tutorial laat ik je zien hoe je Claude Code binnen Docker draait: van het bouwen van een minimale baseline-image tot het orkestreren van een multi-service-applicatie met Docker Compose. Aan het einde heb je een herhaalbare, veilige workflow die je op elk project kunt toepassen.
Voor wie interesse heeft in de nieuwste Anthropic-modellen: lees ook onze gidsen over Claude Opus 4.6 en Claude Sonnet 4.6.
Om te snappen waarom Docker zo natuurlijk past bij Claude Code, helpt het om kort te begrijpen wat elk hulpmiddel precies doet.
Claude Code is Anthropic’s command-line, agentische codingtool, algemeen beschikbaar sinds mei 2025. Het draait in je terminal, leest je codebase en voert taken uit (code refactoren, tests schrijven, git-workflows beheren) via natuurlijke taal. Onze uitgebreide Claude Code 2.1 Tutorial behandelt alles wat je moet weten.
Docker is een platform om applicaties te verpakken en te draaien in lichte, geïsoleerde containers die de host-OS-kernel delen, maar strikte proces- en filesystemgrenzen behouden. Als je helemaal nieuw bent met Docker, raad ik aan om onze gids over het gratis Play with Docker-platform te lezen en daar te experimenteren.
Claude Code heeft een omgeving nodig om te draaien. Docker biedt er een die reproduceerbaar en wegwerpbaar is. Die combinatie is krachtig, maar om er echt alles uit te halen moet je het executiemodel, de security-defaults en de passende deployaanpak voor jouw situatie begrijpen.
Laten we beginnen met hoe een gecontaineriseerde Claude Code-sessie op requestniveau werkt.
Het cruciale onderscheid is tussen vluchtige staat en persistente staat. Alles wat in de container wordt geschreven buiten het gemounte volume, wordt tijdens opruimen verwijderd. Je workspace, die op de host leeft en is gemount, blijft bestaan.
Dit betekent dat tijdelijke dependencies, build-artifacts en toolinstallaties verdwijnen, maar je echte projectbestanden precies zo blijven als Claude ze achterliet. Die scheiding stelt me echt gerust: voordat ik dit begreep, keek ik nerveus mee tijdens agentsessies. Nu start ik een taak en ga ik koffie halen.
Met de uitvoeringsstroom in gedachten is het de moeite waard om expliciet te zijn over wat Docker’s isolatie wel en niet beschermt.
Filesystemisolatie is de belangrijkste securitywinst. Claude Code kan alleen bestanden lezen en schrijven in paden die jij expliciet mount. Als je ze niet in de container mount, zijn je SSH-sleutels, ~/.aws-credentials, host-omgevingsvariabelen en systeemconfiguratiebestanden onzichtbaar voor de agent, tenzij je ze bewust blootstelt. Die bescherming geldt echter alleen als je je mounts zorgvuldig configureert.
Eén cruciale regel: mount nooit de host Docker-socket (/var/run/docker.sock) in de Claude Code-container. Als de agent met de Docker-daemon op je host kan praten, kan hij mogelijk geprivilegieerde containers opstarten, volledig uit de sandbox ontsnappen en roottoegang tot je machine krijgen.
Dit is een bekende weg naar privilege-escalatie zonder goede rechtvaardiging. Ik heb dit in enkele community-Dockerfiles gezien als manier om de agent “containers te laten beheren”, en elke keer wil ik de auteur een stevig bericht sturen.
Los van security-defaults is er nog één beslissing voordat je code schrijft: welk deploymodel past bij jouw usecase? Er zijn drie hoofdopties, en ze zijn niet onderling inwisselbaar.
|
Deploymethode |
Beste voor |
Belangrijkste trade-off |
|
Docker-sandbox (enkele container) |
Geïsoleerde, eenmalige agenttaken |
Geen service-naar-service-netwerk |
|
Docker Compose |
Multi-service-apps in development |
Meer setup, bredere aanvalsoppervlakte |
|
Devcontainers |
Team-brede gestandaardiseerde omgevingen |
Vereist VS Code of een compatibele IDE |
Voor de meeste taken (de agent op een enkele repo draaien, een script debuggen, een module refactoren) is een eenvoudige Docker-sandbox de veiligste default.
Docker Compose is logisch wanneer Claude Code moet interacteren met een draaiende database, API of frontendservice.
Devcontainers zijn de juiste keuze voor team-brede gestandaardiseerde omgevingen met vooraf geconfigureerde IDE-extensies. Opvallend is dat de officiële Anthropic-referentie-devcontainer een ingebouwde firewall heeft die uitgaande verbindingen beperkt tot een vertrouwde allowlist, en juist die isolatie maakt het veilig om Claude Code met --dangerously-skip-permissions volledig onbeheerd te draaien.
In deze tutorial behandelen we zowel de single-container-sandbox als een Compose-setup.
Nu de architectuur en deployopties duidelijk zijn, zorgen we dat de omgeving goed is geconfigureerd voordat we code schrijven. Ik heb te vaak gezien dat deze stap wordt overgeslagen, en het is de meest voorkomende reden dat tutorials als deze halverwege mislopen.
Dit heb je nodig voordat je de eerste docker build uitvoert:
Docker Desktop (macOS of Windows) of Docker Engine (Linux), met de daemon actief draaiend. Op macOS en Windows moet virtualisatie zijn ingeschakeld in je BIOS/firmware-instellingen. Op Linux voeg je je user toe aan de docker-groep met sudo usermod -aG docker $USER, of zet je voor elk Docker-commando sudo.
Node.js v18 of hoger op je hostmachine, omdat de Claude Code CLI een npm-package is. Controleer met node --version.
Een Anthropic API-sleutel, die je kunt genereren in de Claude Console.
Controleer of Docker zelf gezond is met een snelle sanitycheck voordat je verdergaat:
docker run --rm hello-world
Als je Hello from Docker! ziet, reageert je daemon correct en kun je door.
Met een gezonde daemon is het volgende dat goed moet staan: credentials. Je Anthropic API-sleutel injecteren als runtime-omgevingsvariabele is aanzienlijk veiliger dan interactief in de container inloggen.
Dat heb ik de harde weg geleerd: interactieve logins kunnen credentials in containerlagen of shellgeschiedenis schrijven die lang op schijf blijven staan nadat jij ze allang vergeten bent.
Het juiste patroon is het meegeven van de sleutel bij runtime met -e:
docker run --rm -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" my-claude-image
Let op dat ik verwijs naar $ANTHROPIC_API_KEY vanuit mijn hostshell. De sleutel komt niet in de Dockerfile, wordt niet gecommit naar versiebeheer en verschijnt in geen enkele imagelaag. Stel ’m één keer in je shell-profiel in (~/.zshrc of ~/.bashrc), en hij stroomt vanaf dat moment netjes elke container-run in.
Met de authenticatie geregeld is de laatste setupstap het aanmaken van een schone workspace. Ik maak altijd een aparte map voor elke agentsessie in plaats van Claude naar een bestaand project te wijzen, omdat dat de kans elimineert dat de agent afdwaalt naar aangrenzende code die je niet wilde laten aanraken.
mkdir ~/claude-docker-tutorial
cd ~/claude-docker-tutorial
echo "# My Project" > README.md
echo "def hello(): return 'world'" > app.py
Houd deze map schoon. Kopieer je echte .env-bestand of credentials er niet in. De workspace moet alleen de code bevatten waar de agent aan mag werken, en verder niets. Daarmee zijn we klaar om te bouwen.
Met de omgeving geconfigureerd en de concepten helder, is het tijd om te bouwen. Dit deel loopt de stappen door: eerst een minimale single-container-image, dan een werkende sandboxsessie en tot slot een volledige multi-service Compose-stack. Elke stap bouwt voort op de vorige, dus ik raad aan ze op volgorde te volgen in plaats van vooruit te springen.
Alles in dit onderdeel leunt op de securityprincipes die we eerder bespraken. Hier is een minimale Dockerfile die die principes toepast, door de Claude Code CLI te installeren bovenop een slanke Node.js-base-image:
FROM node:20-slim
# Create a non-root user for safer execution
RUN useradd -m -u 1001 claude
# Install Claude Code CLI globally
RUN npm install -g @anthropic-ai/claude-code
# Set the working directory
WORKDIR /workspace
# Switch to non-root user
USER claude
ENTRYPOINT ["claude"]
Een paar ontwerpkeuzes zijn het toelichten waard. Ik gebruik node:20-slim in plaats van node:20-alpine omdat Alpine de musl libc-bibliotheek gebruikt, wat soms compatibiliteitsproblemen geeft met native npm-packages.
Ik liep hier precies tegenaan bij mijn eerste poging met Alpine: de Claude Code CLI installeerde prima, maar crashte bij de eerste run met een cryptische linkerfout die me een uur kostte om terug te voeren naar musl.
De slim-variant is gebaseerd op Debian: lichtgewicht en betrouwbaar, zonder dat gedoe. Bovendien maak ik een aparte claude-user aan en schakel ik daarvóór de entrypoint naartoe, wat betekent dat het agentproces zonder rootrechten draait en zelfs binnen de container beperkt is in wat het kan doen.
Bouw de image met:
docker build -t claude-code:latest .
Bij de eerste build trekt Docker de base-image binnen en installeert de CLI. Bij volgende builds zonder wijzigingen aan de Dockerfile zie je “CACHED” naast elke laag, waardoor rebuilds bijna direct gaan zodra de basis staat.
Met de image gereed is het tijd voor de eerste echte sessie.
Voor read-only-taken zoals het opsommen of samenvatten van bestanden is het basiscommando voldoende:
docker run --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v $(pwd):/workspace \
claude-code:latest \
"List the files in this workspace and describe what each one does."
De -v $(pwd):/workspace mount je huidige directory in de container, zodat het commando vanuit elke projectmap werkt. De --rm-vlag verwijdert de container automatisch na afsluiten.
Voor write-operaties zijn twee extra vlaggen nodig.
De vlag -u $(id -u):$(id -g) geeft de UID en GID van je hostgebruiker door aan de container, zodat het claude-proces permissies heeft om naar je gemounte bestanden te schrijven. Zonder deze vlag krijg je een read-only-filesystemfout omdat de claude-user in de container niet overeenkomt met de file-eigendom op je host.
De vlag --dangerously-skip-permissions slaat de interactieve goedkeuringsprompts van Claude Code over, die nodig zijn bij niet-interactief draaien in een container. De Dockergrens zelf maakt dit veilig.
docker run --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v $(pwd):/workspace \
-u $(id -u):$(id -g) \
claude-code:latest \
--dangerously-skip-permissions \
"Add a docstring to the hello function in app.py."

Claude Code Docker-schrijfbewerking
Controleer daarna je lokale bestand: cat app.py. Zie je de docstring, dan werkt de volumemount in beide richtingen en ben je klaar om op te schalen naar een multi-service-setup.
De single-container-sandbox werkt goed voor geïsoleerde taken, maar echte development omvat vaak meerdere services die tegelijk draaien. Hier bewijst Docker Compose zijn waarde.
Onderstaande configuratie koppelt de Claude Code-agent aan een webservice en een PostgreSQL-database, een representatieve setup voor veel backendprojecten:
services:
claude:
build: .
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
volumes:
- ./workspace:/workspace
depends_on:
db:
condition: service_healthy
networks:
- app-network
web:
image: python:3.12-slim
working_dir: /app
volumes:
- ./workspace:/app
command: python -m http.server 8080
ports:
- "8080:8080"
networks:
- app-network
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: appdb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d appdb"]
interval: 5s
timeout: 3s
retries: 5
networks:
- app-network
networks:
app-network:
driver: bridge
Merk op dat version is weggelaten, omdat dit in moderne Docker Compose verouderd is en een waarschuwing oplevert als je het opneemt.
Twee andere details zijn het benoemen waard:
Ten eerste mount de service claude .:/workspace (de huidige directory) in plaats van een subdirectory. Met ./workspace is een aparte submap nodig en ziet de agent een lege workspace.
Ten tweede wordt DATABASE_URL expliciet doorgegeven zodat de agent Postgres kan bereiken. Zonder die string heeft Claude geen connectiestring en zal hij erom vragen.
De regel user: "${UID}:${GID}" past dezelfde host-UID/GID-override toe die we in de losse docker run-commando’s gebruikten, zodat schrijfacties op bestanden goed werken. Exporteer beide voordat je draait:
export UID=$(id -u) GID=$(id -g)
De service claude heeft geen persistente command, dus anders dan web en db is hij niet bedoeld om continu te draaien. Start eerst de ondersteunende services en roep Claude daarna on demand aan met docker compose run:
# Start de database en webservice
docker compose up -d web db
# Voer een eenmalige Claude-taak uit
docker compose run --rm \
claude \
--dangerously-skip-permissions \
"Check the database connection and summarize the schema in README.md."

Claude Code met Docker Compose
Start eerst de ondersteunende services met docker compose up -d web db en bekijk daarna hun logs met docker compose logs -f. Let op de depends_on met condition: service_healthy.
Ik sloeg dit over in een vroeg project en was 20 minuten bezig met het najagen van databaseverbindingsfouten voordat ik besefte dat Claude was gestart voordat Postgres klaar was. De healthcheck kost niets en voorkomt precies die hoofdpijn.
Als je sessie is afgerond, is opruimen net zo belangrijk als de setup. Weescontainers gebruiken geheugen en verstoren toekomstige runs; naar mijn ervaring is dit de stap die de meeste developers overslaan totdat er iets vreemd gaat doen.
Hier zijn de meest gebruikte commando’s en wanneer je ze inzet:
|
Commando |
Wat het doet |
Wanneer te gebruiken |
|
|
Stopt en verwijdert alle containers in de stack |
Na elke Compose-sessie |
|
|
Verwijdert alle gestopte containers |
Als je --rm vergat bij een losse run |
|
|
Verwijdert containers, netwerken en named volumes |
Volledige reset, wist databasetoestand |
|
|
Toont draaiende containers |
Bevestigen dat er niets meer actief is |
The vlag -v bij docker compose down is degene om voorzichtig mee te zijn. Hij verwijdert named volumes, wat betekent dat alle databasedata die je in Postgres hebt opgebouwd weg is. Ik gebruik ’m alleen als ik echt een schone lei wil. Anders is alleen docker compose down voldoende.
Met de kernworkflow op orde, kijken we hoe je die uitbreidt en hoe je debugt als er iets stukgaat.
Claude Code ondersteunt het omleiden van inference naar elke Anthropic-compatibele lokale endpoint via ANTHROPIC_BASE_URL. Docker Model Runner, ingebouwd in Docker Desktop, biedt precies zo’n API, waardoor de integratie native is binnen het Docker-ecosysteem.
Pull een model en wijs Claude Code naar de lokale endpoint:
docker model pull ai/smollm2
ANTHROPIC_BASE_URL=http://localhost:12434 claude --model ai/smollm2 "List the files of the repository."
Dit is een ander patroon dan de eerder besproken gecontaineriseerde sandboxaanpak. Hier draait Claude Code op je host, en blijft de inference lokaal via Docker Model Runner, zodat er geen API-call je machine verlaat.
Naast lokale modellen kun je het bereik van Claude Code uitbreiden via MCP (Model Context Protocol)-servers. Als je er niet bekend mee bent, is onze MCP-gids een prima startpunt.
De MCP Toolkit van Docker levert meer dan 200 kant-en-klare, gecontaineriseerde MCP-servers voor onder meer GitHub, Jira en Supabase, waardoor Claude Code met permissies toegang krijgt tot die tools zonder ruwe API-credentials bloot te stellen.
Samen geven deze twee extensiepunten je wezenlijke controle over waar de inference plaatsvindt en welke externe services de agent kan bereiken.
Als je Dockerfile groeit, kan buildtijd een bottleneck worden. Multi-stage builds lossen dit op door installatie te scheiden van de runtime-image:
# Build stage
FROM node:20-slim AS builder
RUN npm install -g @anthropic-ai/claude-code
# Runtime stage
FROM node:20-slim
COPY --from=builder /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=builder /usr/local/bin/claude /usr/local/bin/claude
RUN useradd -m -u 1001 claude
USER claude
WORKDIR /workspace
ENTRYPOINT ["claude"]
De laagvolgorde is net zo belangrijk als de structuur, en dit had ik langer mis dan ik wil toegeven.
Zelden veranderende instructies (zoals systeempackages installeren) gaan bovenaan. Vaak veranderende (zoals sourcebestanden kopiëren) gaan onderaan. Zo maximaliseer je cachehits en maak je rebuilds van 30 seconden bijna direct.
Zelfs met een goede setup kan er iets stukgaan. Hier is een herhaalbare debugloop voor de issues die ik het vaakst zie. Eerst het symptoom, dan het commando:
Geblokkeerde netwerk-egress: Claude Code kan de Anthropic API niet bereiken. Draai docker run --rm alpine wget -qO- https://api.anthropic.com om uitgaande toegang te verifiëren. Als dit faalt, controleer docker network inspect bridge op proxy-instellingen.
Onjuiste volumemounts: Claude Code meldt dat hij geen bestanden kan vinden. Draai docker run --rm -v $(pwd):/workspace alpine ls /workspace. Een lege listing betekent dat je pad niet klopt. Bevestig eerst dat de directory bestaat.
Stale buildcache: Je hebt je Dockerfile bijgewerkt, maar het gedrag is niet veranderd. Forceer een volledige rebuild met docker build --no-cache -t claude-code:latest ..
Service-naar-service-verbindingen falen in Compose: Eén service kan een andere niet bereiken. Services communiceren via hun servicenamen (db, web), niet via localhost. Draai docker compose exec web ping db om bereikbaarheid te testen. Een mislukte ping betekent dat de services niet op hetzelfde netwerk zitten.
Claude Code binnen Docker draaien levert je iets wezenlijks op: de vrijheid om een autonome agent vrij te laten werken, wetend dat wat hij kan aanraken strikt begrensd is.
In deze tutorial heb ik laten zien hoe je een minimale non-root-containerimage bouwt, workspacevolumes beheert, multi-service-applicaties orkestreert met Docker Compose en de meest voorkomende integratiefouten diagnosticeert.
De setup kostte me ongeveer een middag om goed te krijgen, en het veranderde volledig hoe ik agent-assisted development aanpak. Ik delegeer hele taken in plaats van elke stap te volgen, en de Dockergrens maakt dat mogelijk.
Vanaf hier zijn twee richtingen het verkennen waard:
Kijk ten eerste naar devcontainer-templates voor je team. De Claude Code-referentie-devcontainer op GitHub heeft een vooraf geconfigureerde firewall die uitgaande verbindingen beperkt tot vertrouwde domeinen. Experimenteer ten tweede met Docker MCP Toolkit om Claude Code gestructureerde toegang te geven tot je bestaande tools: GitHub, databases, projectmanagementsystemen en meer.
Zet tot slot een reminder om je base-images periodiek te updaten. Docker-images stapelen na verloop van tijd kwetsbaarheden op, en een snelle docker pull node:20-slim gevolgd door een rebuild kost maar een paar minuten.
Als je geïnteresseerd bent in het ontwikkelen van AI-applicaties, raad ik je sterk aan om je in te schrijven voor onze skill track AI Engineering with LangChain. De cursussen zijn AI-native, dus je krijgt een persoonlijke docent die je oppakt op jouw exacte niveau en je helpt je doelen te bereiken in je eigen tempo.
Voeg een claude-service toe aan je Compose-bestand met je API-sleutel als omgevingsvariabele en je projectdirectory gemount als volume. Gebruik docker compose run --rm claude om hem on demand aan te roepen in plaats van hem continu te laten draaien zoals je web- of databaseservices.
Standaard vraagt Claude Code om goedkeuring voordat hij bestanden schrijft. In een container kunnen die prompts niet interactief worden beantwoord, dus geef je --dangerously-skip-permissions mee om ze over te slaan. De Dockergrens zelf maakt dit veilig. De agent kan alleen bestanden aanraken in je gemounte workspace.
Claude Code ondersteunt aangepaste inference-endpoints via ANTHROPIC_BASE_URL. Je kunt hem richten op Docker Model Runner om modellen zoals ai/smollm2 volledig op je lokale machine te draaien, zonder dat API-calls je host verlaten.
Mount alleen de subdirectory die de agent nodig heeft in plaats van je hele repo, gebruik een CLAUDE.md-bestand om de agent context te geven over je projectstructuur, en draai /init binnen de sessie zodat Claude Code de codebase kan indexeren voordat hij start.
De belangrijkste beperking is de contextvenstergrootte. Claude Code kan alleen redeneren over wat in zijn actieve context past, dus zeer grote codebases vereisen dat je taken scopeert tot specifieke modules. Voor multi-service-setups moeten services op hetzelfde Docker-netwerk zitten, en de claude-service heeft expliciete omgevingsvariabelen nodig voor alle database- of API-connectiestrings die hij moet bereiken.
Als oprichter van Martin Data Solutions en freelance data scientist, ML- en AI-engineer heb ik een divers portfolio in regressie, classificatie, NLP, LLM, RAG, neurale netwerken, ensemblemethoden en computer vision.
In elk project dat ik aanpak, pas ik actuele praktijken uit software-engineering en DevOps toe, zoals CI/CD, codelinting, formattering, modelmonitoring, experimenttracking en robuuste foutafhandeling. Ik zet me in om complete oplossingen te leveren en data-inzichten te vertalen naar praktische strategieën die bedrijven helpen groeien en het maximale halen uit data science, machine learning en AI.
Top AI-cursussen
Leerpad
Cursus
Cursus

blog
Adel Nehme
15 min