Adding Containers with Claude Code
The repository ships a Claude Code skill that walks through adding a new container to the stack. It encodes the same steps as Adding New Containers, plus the conventions and the mistakes that are easy to make.
This is a contributor tool. You do not need it to run HMS-Docker, and it is not involved in the playbook at runtime — it only helps you write the files for a pull request.
What it is
Section titled “What it is”A skill is a folder of instructions that Claude Code loads when the task matches. This one lives in the repository, so anyone who clones the repo gets it automatically — there is nothing to install or enable.
Directory.claude/
Directoryskills/
Directoryadd-container/
- SKILL.md # The workflow and the decision rules
Directoryreference/
- template-anatomy.md # Annotated Compose template, block by block
- variants.md # Non-standard shapes (GPU, VPN, host networking, sidecars)
Claude Code reads the description in SKILL.md to decide when the skill applies, and only loads the reference files when it needs them.
Requirements
Section titled “Requirements”- Claude Code installed and authenticated
- A clone of this repository, with Claude Code started from the repository root
Using it
Section titled “Using it”-
Start Claude Code in the repository:
Terminal window cd ansible-hms-dockerclaude -
Ask for the container. The skill triggers on its own for requests like these — you do not have to name it:
add byparr to the stackYou can also invoke it explicitly:
/add-container -
Answer the questions it asks. It needs the container image, the port the app listens on inside the container, whether the service needs access to your media (
/data), and whether it should be behind Traefik and shown on Homepage. If you do not know the image or port, say so rather than guessing — a wrong port produces a 502 through Traefik with no other symptom. -
Review the diff. At minimum, read the generated
roles/hmsdocker/templates/containers/<name>.yml.j2and the newcontainer_map.ymlentry, and confirm the entry landed between its alphabetical neighbours without disturbing them. -
Test it. Enable the service in
inventory/group_vars/all/container_map.yml, then runmake checkandmake applyagainst a throwaway host.
What it produces
Section titled “What it produces”Two files are always written:
| File | Purpose |
|---|---|
roles/hmsdocker/defaults/main/container_map.yml |
the map entry, inserted alphabetically, with enabled: false |
roles/hmsdocker/templates/containers/<name>.yml.j2 |
the Compose fragment |
Anything else is added only when the service actually needs it — a container_prereqs/container_postreqs task file, an env.j2 variable, a service_misc.yml tunable, a Homepage credential, or a restart handler.
It also updates the user-facing pieces: the category bullet and the Map table row on the Container List page, a release-notes entry, the hmsd_current_version bump in hms-docker.yml, and the CI container map in .github/extra-vars.yml.
What it will not do
Section titled “What it will not do”- Enable the service by default. New containers ship
enabled: false. - Edit
docker-compose.yml.j2. The top-level Compose file builds itsinclude:list automatically from the rendered fragments. - Add a Traefik dynamic-config entry. Routers come from container labels.
- Register the task files. Files dropped into
container_prereqs/,container_postreqs/andapp_inits/are discovered by filename. - Run
make apply. It will offermake check, but it does not mutate the host on its own.
Checks it runs
Section titled “Checks it runs”Before finishing, the skill runs a handful of read-only checks against the working tree:
- Every container map key has a matching template file, and vice versa
- No two containers publish the same host port
- The new template only references derived facts that actually exist (
traefik_enabled_containers,homepage_enabled_containers, and so on) - The map entry parses, and its alphabetical neighbours are intact
Editing the skill
Section titled “Editing the skill”The skill is a plain Markdown file — edit .claude/skills/add-container/SKILL.md like any other file in the repository. If you change how containers are structured (a new required block in the Compose template, a new map key, a renamed derived fact), update the skill in the same pull request so it does not drift from the code.