A Docker harness for testing Claude skills from scratch
A throwaway container with a fresh Claude Code install is the cheapest clean machine there is. A minimal Dockerfile, what to mount, and what to look for.
The honest test of a skill is a machine that has never seen it. A container gives you one in seconds and throws it away afterwards, so every run starts clean.
A minimal image
FROM node:20-slim
RUN npm install -g @anthropic-ai/claude-code
WORKDIR /work
# the skill is mounted, not copied, so you test the working tree
# docker run -e ANTHROPIC_API_KEY -v "$PWD/my-skill:/root/.claude/skills/my-skill" ...Keep the image close to what users have: a current Node, no extra CLI tools unless the skill documents them as requirements. The point is to fail where users would fail.
Run the prompts non-interactively
Claude Code can take a prompt and print the answer without an interactive session, which makes it scriptable. Feed it your trigger test set one prompt at a time and save each output to a file.
What a failed run usually means
| Symptom | Usual cause |
|---|---|
| Skill not listed | SKILL.md nested one folder too deep, or bad frontmatter |
| Script error on first use | A dependency your machine had and the container does not |
| Different output than locally | A local config file or CLAUDE.md shaping results |
The reasoning behind clean-machine testing is in test a skill on a clean machine; automating the same run on every change is in testing skills in CI.
Questions
Why test a skill in Docker instead of my own machine?
Your machine has every tool, config file and cached credential the skill might quietly depend on. A fresh container has none of them, like a new user's laptop.
How does Claude Code authenticate inside the container?
Pass credentials in at run time, for example an API key as an environment variable. Never bake a key into the image.
What should I check after a container run?
Whether the skill loaded, whether it fired on the prompts it should, whether any script failed for a missing dependency, and what the output looked like.