headroom.walls.sh · docker

Claude Code + Docker

Claude Code handles Docker work well: generating Dockerfiles from a description of what the container needs to do, optimizing slow builds by reorganizing layers, debugging Compose networking issues, and writing multi-stage builds that actually fit in a reasonable image size. This page covers the patterns that save time.

Writing Dockerfiles from scratch

Describe what the container needs to run and Claude Code writes a Dockerfile:

claude "write a Dockerfile for a Node.js 20 Express API that runs on port 3000. Use the slim base image, non-root user, and copy only what's needed to run in production."
claude "write a Dockerfile for a Python FastAPI app. Use multi-stage: a build stage that installs all deps, and a runtime stage that copies only the app and installed packages."

It reads your package.json, requirements.txt, or go.mod before writing to include the right install commands, entry points, and exposed ports — no generic templates.

Multi-stage builds

Multi-stage builds reduce image size by separating build-time dependencies from runtime. Claude Code writes them correctly:

claude "convert the Dockerfile to a multi-stage build. Builder stage: install all dev dependencies and run the TypeScript compile. Runtime stage: copy only dist/ and node_modules (prod only). Target the runtime stage in the final image."
claude "the Docker image is 1.2GB. Read the Dockerfile and suggest multi-stage changes to get it under 200MB. Show the size savings at each layer."

Claude Code can also analyze an existing Dockerfile and explain exactly where the bulk comes from — which layers, which packages — before rewriting it.

Layer caching optimization

Slow Docker builds are usually a layer ordering problem. Dependencies that change rarely should be copied and installed before code that changes frequently:

claude "read the Dockerfile — the build is slow because npm install runs on every code change. Reorder the layers so COPY package.json and npm install come before COPY src/. Verify the build cache works correctly after."
claude "the Go service Dockerfile copies the full source tree before running go build. Fix the layer order: copy go.mod and go.sum first, run go mod download, then copy source."
The rule is: layers that change rarely go first, layers that change often go last. COPY package.json and npm install belong before COPY . . — package.json changes less often than source files, so Docker reuses that cached layer on most builds.

Docker Compose debugging

When services can't reach each other, volumes aren't mounting, or healthchecks are failing:

claude "read docker-compose.yml — the frontend container can't reach the api container. Diagnose the networking issue and fix it. Check service names, network definitions, and port mappings."
claude "the postgres container starts but the app container fails with connection refused. Read the docker-compose.yml and the app's database connection code. Find why the app is connecting before postgres is ready and fix it with a healthcheck."
claude "the volume mount in docker-compose.yml isn't persisting data between restarts. Read the config and fix the volume definition."

Claude Code reads both the Compose config and the application code that depends on it — it can see when the app is using a hardcoded hostname that doesn't match the Compose service name, or when the healthcheck condition is wrong.

Container networking

claude "add a custom bridge network to docker-compose.yml so the services can reference each other by name. The frontend needs to reach the api, the api needs to reach the database."
claude "the nginx container is proxying to the app container. Read the nginx.conf and docker-compose.yml — the proxy_pass target is wrong. Fix it so nginx can reach the app on the correct internal port."

Running Claude Code inside a container

To run Claude Code in a containerized environment (CI, isolated dev, remote server):

# Install Node.js and Claude Code in a Dockerfile
RUN apt-get update && apt-get install -y nodejs npm
RUN npm install -g @anthropic-ai/claude-code

For CI pipelines using Docker:

# In GitHub Actions, run Claude Code in a container step
- name: Run Claude Code task
  run: |
    claude --print "review this diff for bugs" < diff.txt

See the CI integration page for full GitHub Actions workflows with Claude Code.

Writing docker-compose.yml from scratch

claude "write a docker-compose.yml for a web app with: a Node.js API on port 3000, a PostgreSQL database with a named volume, and a Redis cache. Include healthchecks and the correct depends_on conditions."
claude "add a development override file (docker-compose.override.yml) that mounts the src/ directory as a volume and enables hot reload for the API service."

Debugging image size and build issues

claude "run docker images and show me the largest layers in the app image. Find what's adding bulk and suggest removals."
claude "the Docker build fails with a permission error on the COPY step. Read the Dockerfile and the .dockerignore — find why the file can't be copied and fix it."
claude "add a .dockerignore file for this Node.js project — exclude: node_modules, .git, test files, coverage reports, and local .env files."

Headroom — session usage while Docker builds run

Debugging a tricky Compose networking issue or iterating on a multi-stage build optimization can burn through Claude Code session budget quickly — each build-run-inspect cycle accumulates tool calls. Headroom shows your 5h session and 7d weekly utilization live in the macOS menu bar.

Install in one line:

brew install patwalls/tap/headroom

No token, no API key — reads the file Claude Code writes to ~/.claude/. Color-coded from calm to amber to red.


Claude Code in GitHub Actions and CI
Refactoring with Claude Code
Debugging with Claude Code
5-hour session limit explained