
Containerize a Service
Containerize an application with a production-grade Dockerfile — small, secure, reproducible, and buildable — plus the supporting files to run it. Scopes the container contract FIRST — base image, build vs runtime stages, dependencies, exposed port, entrypoint, env config, and the size/security bar — then writes the Dockerfile + .dockerignore + compose, then a reviewer confirms it builds, runs, and meets the bar. Covers multi-stage builds, slim base images, layer caching, non-root user, .dockerignore, healthchecks, EXPOSE/ENTRYPOINT, and reproducible image builds.
Steps
Entry step: scope. Each step names the specialist role it wants; the full working prompt is expandable.
- Scope the containerplannerentry
lock base image, stages, port, entrypoint, bar
Show working prompt
Scope the container before writing the Dockerfile. Step 1: Identify the runtime (language/version) and pick a slim, pinned base image. Step 2: Decide the build strategy: a multi-stage build (build deps in one stage, copy only artifacts to a slim runtime stage) and what gets copied forward. Step 3: List the dependencies to install, the port to EXPOSE, the ENTRYPOINT/CMD, and the env vars the app needs at runtime. Step 4: Set the bar: run as a non-root user, a .dockerignore that excludes junk, a healthcheck, and a rough image-size target. Step 5: Write a numbered acceptance-criteria checklist of 5-9 items (e.g. 'docker build succeeds from a clean context', 'the container starts and serves on the exposed port', 'runs as non-root', 'final image uses a multi-stage slim base'). `write_task_note` the scope + checklist and write the same to the produces path.
- Write the Dockerfiledeveloper
implement the multi-stage Dockerfile + support files
Show working prompt
Author the containerization files to the scope. Step 1: Write a multi-stage `Dockerfile` — a build stage that installs deps and builds, then a slim runtime stage that copies only the needed artifacts. Step 2: Order layers for cache efficiency (copy manifest + install deps BEFORE copying source), pin the base image, set a non-root USER, EXPOSE the port, and define ENTRYPOINT/CMD and a HEALTHCHECK. Step 3: Write a `.dockerignore` that excludes node_modules, .git, build output, and secrets. Step 4: If a service needs orchestration, add a minimal compose/run file. Step 5: Build the image and confirm it succeeds and the container starts. Write the Dockerfile to the produces path. On a loop-back, fix only the named gaps. `write_task_note` the file paths and which criteria now pass.
- Verify the imagereviewer
confirm it builds, runs, and meets the bar
Show working prompt
Verify the container build. Step 1: Build the image from a clean context and confirm the build succeeds. Step 2: Run the container and confirm it starts and serves on the exposed port (hit the healthcheck/endpoint). Step 3: Confirm the bar: multi-stage slim base, non-root user, a real .dockerignore, pinned base image, and a sane final size. Step 4: Confirm no secrets or junk were baked into the image layers. Write a verification note with the build result, run check, and size to the produces path.
- Evaluatereviewer
Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.
Show working prompt
Build and run the image. For EACH acceptance criterion: confirm `docker build` succeeds from a clean context, confirm the container starts and serves on the exposed port, confirm it runs as non-root with a multi-stage slim base and a .dockerignore, and confirm no secrets/junk were baked in. Write PASS/FAIL per criterion. Then route — this is the whole point of the loop: - **Every criterion PASSES →** call `advance_task_step({ ref, stepId: "evaluate", next: "finish" })`. - **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: "evaluate", next: "build" })` to loop back. The builder fixes exactly those gaps. Never route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in. - Finishdeveloper
All acceptance criteria met. Stamp a short summary and report DONE.
Show working prompt
Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.
Triggers
Phrases that suggest this craftbook to a crew.
- dockerize this app
- write a dockerfile
- containerize a service
- create a docker image
- docker compose setup
Source
View this craftbook on GitHub · MIT license