#33 — Docker Development Container #33

Closed
opened 2026-08-18 13:13:02 +02:00 by lena · 0 comments
lena commented 2026-08-18 13:13:02 +02:00 (Migrated from git.butzei.de)

Story #33: Docker Development Container

As a developer (human or AI agent),
I want to run the entire development environment inside a Docker container,
so that I can build, run, test, and screenshot the application without any local tooling installed on the host.


Background

Today, development requires the host to have .NET 10 SDK, Node.js 22, PostgreSQL, Redis, and Playwright browsers installed separately. This makes onboarding slow and prevents AI agents (Claude Code) from developing autonomously in a clean, reproducible environment. A self-contained dev container solves both problems.


Acceptance criteria

  • A single docker compose -f docker-compose.dev.yml up -d starts the full dev environment (app container + PostgreSQL + Redis)
  • The dev container includes: .NET 10 SDK, Node.js 22, npm, TypeScript tools, Playwright with Chromium, Claude Code CLI
  • dotnet build and dotnet test succeed inside the container
  • npm run build, npm test, and npx playwright test succeed inside the container
  • Playwright can take screenshots of the running application from inside the container (headless Chromium)
  • Claude Code (claude) is available inside the container and can be launched by passing ANTHROPIC_API_KEY via environment variable
  • The project source is bind-mounted so edits made inside the container are reflected on the host (and vice versa)
  • A .env.dev.example documents the required environment variables for the dev setup
  • A usage guide in docs/dev-container.md explains how to start the container, run services, execute tests, and take screenshots

Files to be created / changed

File Purpose
Dockerfile.dev Multi-tool dev image (SDK + runtime + browsers + Claude Code)
docker-compose.dev.yml Dev orchestration (devbox + postgres + redis)
.env.dev.example Template for required env vars
docs/dev-container.md Usage guide for humans and AI agents

Existing Dockerfile and docker-compose.yml are not modified — they remain for production deployments.


Technical design notes for Architect

Base image

Use mcr.microsoft.com/dotnet/sdk:10.0 (Debian-based) as the base — it already includes the .NET SDK and is glibc-based, which Playwright requires.

Tool layers (order matters for layer caching)

  1. System packages: curl, git, unzip, gnupg, ca-certificates, libgssapi-krb5-2 (for .NET), libicu-dev
  2. Node.js 22 via NodeSource script
  3. npm install -g @anthropic-ai/claude-code — installs the claude CLI
  4. Playwright system dependencies: npx playwright install-deps chromium requires root; run during image build
  5. Playwright Chromium browser: npx playwright install chromium

Playwright headless screenshots

Playwright headless Chromium does not require a display server (no Xvfb). Set PLAYWRIGHT_BROWSERS_PATH=/ms-playwright and install at build time so the browser is baked into the image.

Port exposure

Port Service
5000 .NET WebAPI (HTTP)
5173 Vite dev server (React UI)
5432 PostgreSQL (internal)
6379 Redis (internal)

Environment variables required at runtime

ANTHROPIC_API_KEY=sk-ant-...        # Required to run Claude Code
ASPNETCORE_ENVIRONMENT=Development
ConnectionStrings__TodoDatabase=Host=db;Database=cqstodo;Username=cqstodo;Password=dev
ConnectionStrings__redis=redis:6379
App__FrontendBaseUrl=http://localhost:5173

Bind mount strategy

Mount the project root to /workspace inside the container. The working directory for all commands is /workspace. This preserves the host's git history and allows IDE tools on the host to keep working.


Out of scope

  • Hot-reload configuration inside the container (developers can set this up manually)
  • GPU acceleration for Playwright
  • Multi-container Claude agent coordination
  • CI pipeline changes (CI uses the production Dockerfile today)

Usage guide (draft — final version goes in docs/dev-container.md)

Prerequisites

  • Docker Engine 24+ and Docker Compose v2
  • An Anthropic API key

First-time setup

# 1. Copy environment template
cp .env.dev.example .env.dev

# 2. Fill in your Anthropic API key in .env.dev
#    ANTHROPIC_API_KEY=sk-ant-...

# 3. Build the dev image (only needed once, or after Dockerfile.dev changes)
docker compose -f docker-compose.dev.yml build

# 4. Start all services in the background
docker compose -f docker-compose.dev.yml up -d

# 5. Run database migrations
docker compose -f docker-compose.dev.yml exec devbox \
  dotnet run --project CqsTodo.MigrationService

Daily development

# Open a shell in the dev container
docker compose -f docker-compose.dev.yml exec devbox bash

# Inside the container — start the backend
dotnet run --project CqsTodo.WebApi &

# Inside the container — start the frontend dev server
cd ReactUi && npm run dev &

# Run .NET unit tests
dotnet test

# Run frontend unit tests
cd ReactUi && npm test

# Run Playwright E2E tests (app must be running first)
cd ReactUi && npx playwright test

# Launch Claude Code (interactive)
claude

Autonomous AI agent mode

# Run Claude Code non-interactively with a prompt
docker compose -f docker-compose.dev.yml exec devbox \
  claude --print "Implement feature X as described in docs/features/ready/33_docker_dev_container.md"

Taking a screenshot

Claude Code can use Playwright inside the container to capture the UI:

cd ReactUi && npx playwright screenshot --browser chromium http://localhost:5173 /workspace/screenshot.png

Stopping

docker compose -f docker-compose.dev.yml down

Data is stored in a named Docker volume (todo_dev_postgres) and persists across restarts. To reset the database: docker compose -f docker-compose.dev.yml down -v.

# Story `#33`: Docker Development Container **As a** developer (human or AI agent), **I want to** run the entire development environment inside a Docker container, **so that** I can build, run, test, and screenshot the application without any local tooling installed on the host. --- ## Background Today, development requires the host to have .NET 10 SDK, Node.js 22, PostgreSQL, Redis, and Playwright browsers installed separately. This makes onboarding slow and prevents AI agents (Claude Code) from developing autonomously in a clean, reproducible environment. A self-contained dev container solves both problems. --- ## Acceptance criteria - [ ] A single `docker compose -f docker-compose.dev.yml up -d` starts the full dev environment (app container + PostgreSQL + Redis) - [ ] The dev container includes: .NET 10 SDK, Node.js 22, npm, TypeScript tools, Playwright with Chromium, Claude Code CLI - [ ] `dotnet build` and `dotnet test` succeed inside the container - [ ] `npm run build`, `npm test`, and `npx playwright test` succeed inside the container - [ ] Playwright can take screenshots of the running application from inside the container (headless Chromium) - [ ] Claude Code (`claude`) is available inside the container and can be launched by passing `ANTHROPIC_API_KEY` via environment variable - [ ] The project source is bind-mounted so edits made inside the container are reflected on the host (and vice versa) - [ ] A `.env.dev.example` documents the required environment variables for the dev setup - [ ] A usage guide in `docs/dev-container.md` explains how to start the container, run services, execute tests, and take screenshots --- ## Files to be created / changed | File | Purpose | |---|---| | `Dockerfile.dev` | Multi-tool dev image (SDK + runtime + browsers + Claude Code) | | `docker-compose.dev.yml` | Dev orchestration (devbox + postgres + redis) | | `.env.dev.example` | Template for required env vars | | `docs/dev-container.md` | Usage guide for humans and AI agents | Existing `Dockerfile` and `docker-compose.yml` are **not modified** — they remain for production deployments. --- ## Technical design notes for Architect ### Base image Use `mcr.microsoft.com/dotnet/sdk:10.0` (Debian-based) as the base — it already includes the .NET SDK and is glibc-based, which Playwright requires. ### Tool layers (order matters for layer caching) 1. System packages: `curl`, `git`, `unzip`, `gnupg`, `ca-certificates`, `libgssapi-krb5-2` (for .NET), `libicu-dev` 2. Node.js 22 via NodeSource script 3. `npm install -g @anthropic-ai/claude-code` — installs the `claude` CLI 4. Playwright system dependencies: `npx playwright install-deps chromium` requires root; run during image build 5. Playwright Chromium browser: `npx playwright install chromium` ### Playwright headless screenshots Playwright headless Chromium does **not** require a display server (no Xvfb). Set `PLAYWRIGHT_BROWSERS_PATH=/ms-playwright` and install at build time so the browser is baked into the image. ### Port exposure | Port | Service | |---|---| | 5000 | .NET WebAPI (HTTP) | | 5173 | Vite dev server (React UI) | | 5432 | PostgreSQL (internal) | | 6379 | Redis (internal) | ### Environment variables required at runtime ``` ANTHROPIC_API_KEY=sk-ant-... # Required to run Claude Code ASPNETCORE_ENVIRONMENT=Development ConnectionStrings__TodoDatabase=Host=db;Database=cqstodo;Username=cqstodo;Password=dev ConnectionStrings__redis=redis:6379 App__FrontendBaseUrl=http://localhost:5173 ``` ### Bind mount strategy Mount the project root to `/workspace` inside the container. The working directory for all commands is `/workspace`. This preserves the host's git history and allows IDE tools on the host to keep working. --- ## Out of scope - Hot-reload configuration inside the container (developers can set this up manually) - GPU acceleration for Playwright - Multi-container Claude agent coordination - CI pipeline changes (CI uses the production `Dockerfile` today) --- ## Usage guide (draft — final version goes in `docs/dev-container.md`) ### Prerequisites - Docker Engine 24+ and Docker Compose v2 - An Anthropic API key ### First-time setup ```bash # 1. Copy environment template cp .env.dev.example .env.dev # 2. Fill in your Anthropic API key in .env.dev # ANTHROPIC_API_KEY=sk-ant-... # 3. Build the dev image (only needed once, or after Dockerfile.dev changes) docker compose -f docker-compose.dev.yml build # 4. Start all services in the background docker compose -f docker-compose.dev.yml up -d # 5. Run database migrations docker compose -f docker-compose.dev.yml exec devbox \ dotnet run --project CqsTodo.MigrationService ``` ### Daily development ```bash # Open a shell in the dev container docker compose -f docker-compose.dev.yml exec devbox bash # Inside the container — start the backend dotnet run --project CqsTodo.WebApi & # Inside the container — start the frontend dev server cd ReactUi && npm run dev & # Run .NET unit tests dotnet test # Run frontend unit tests cd ReactUi && npm test # Run Playwright E2E tests (app must be running first) cd ReactUi && npx playwright test # Launch Claude Code (interactive) claude ``` ### Autonomous AI agent mode ```bash # Run Claude Code non-interactively with a prompt docker compose -f docker-compose.dev.yml exec devbox \ claude --print "Implement feature X as described in docs/features/ready/33_docker_dev_container.md" ``` ### Taking a screenshot Claude Code can use Playwright inside the container to capture the UI: ```bash cd ReactUi && npx playwright screenshot --browser chromium http://localhost:5173 /workspace/screenshot.png ``` ### Stopping ```bash docker compose -f docker-compose.dev.yml down ``` Data is stored in a named Docker volume (`todo_dev_postgres`) and persists across restarts. To reset the database: `docker compose -f docker-compose.dev.yml down -v`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
robert/todo#33
No description provided.