storkit: create 329_spike_evaluate_docker_orbstack_for_agent_isolation_and_resource_limiting
This commit is contained in:
10
docker/.dockerignore
Normal file
10
docker/.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
||||
# Docker build context exclusions
|
||||
target/
|
||||
frontend/node_modules/
|
||||
frontend/dist/
|
||||
.storkit/worktrees/
|
||||
.storkit/work/6_archived/
|
||||
.git/
|
||||
*.swp
|
||||
*.swo
|
||||
.DS_Store
|
||||
115
docker/Dockerfile
Normal file
115
docker/Dockerfile
Normal file
@@ -0,0 +1,115 @@
|
||||
# Story Kit – single-container runtime
|
||||
# All components (server, agents, web UI) run inside this container.
|
||||
# The target project repo is bind-mounted at /workspace.
|
||||
#
|
||||
# Build: docker build -t storkit -f docker/Dockerfile .
|
||||
# Run: docker compose -f docker/docker-compose.yml up
|
||||
#
|
||||
# Tested with: OrbStack (recommended on macOS), Docker Desktop (slower bind mounts)
|
||||
|
||||
FROM rust:1.90-bookworm AS base
|
||||
|
||||
# ── System deps ──────────────────────────────────────────────────────
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
build-essential \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
# cargo-nextest is a pre-built binary
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ── Node.js 22.x (matches host) ─────────────────────────────────────
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ── cargo-nextest (test runner) ──────────────────────────────────────
|
||||
RUN curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C /usr/local/bin
|
||||
|
||||
# ── Claude Code CLI ──────────────────────────────────────────────────
|
||||
# Claude Code is distributed as an npm global package.
|
||||
# The CLI binary is `claude`.
|
||||
RUN npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# ── Biome (frontend linter) ─────────────────────────────────────────
|
||||
# Installed project-locally via npm install, but having it global avoids
|
||||
# needing node_modules for CI-style checks.
|
||||
|
||||
# ── Working directory ────────────────────────────────────────────────
|
||||
# /app holds the storkit source (copied in at build time for the binary).
|
||||
# /workspace is where the target project repo gets bind-mounted at runtime.
|
||||
WORKDIR /app
|
||||
|
||||
# ── Build the storkit server binary ─────────────────────────────────
|
||||
# Copy the full project tree so `cargo build` and `npm run build` (via
|
||||
# build.rs) can produce the release binary with embedded frontend assets.
|
||||
COPY . .
|
||||
|
||||
# Build frontend deps first (better layer caching)
|
||||
RUN cd frontend && npm ci
|
||||
|
||||
# Build the release binary (build.rs runs npm run build for the frontend)
|
||||
RUN cargo build --release \
|
||||
&& cp target/release/storkit /usr/local/bin/storkit
|
||||
|
||||
# ── Runtime stage (smaller image) ───────────────────────────────────
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
libssl3 \
|
||||
# build-essential (gcc/cc) needed at runtime for:
|
||||
# - rebuild_and_restart (cargo build --release)
|
||||
# - agent-driven cargo commands (clippy, test, build)
|
||||
build-essential \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Node.js in runtime
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Claude Code CLI in runtime
|
||||
RUN npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# Cargo and Rust toolchain needed at runtime for:
|
||||
# - rebuild_and_restart (cargo build inside the container)
|
||||
# - Agent-driven cargo commands (cargo clippy, cargo test, etc.)
|
||||
COPY --from=base /usr/local/cargo /usr/local/cargo
|
||||
COPY --from=base /usr/local/rustup /usr/local/rustup
|
||||
ENV PATH="/usr/local/cargo/bin:${PATH}"
|
||||
ENV RUSTUP_HOME="/usr/local/rustup"
|
||||
ENV CARGO_HOME="/usr/local/cargo"
|
||||
|
||||
# cargo-nextest
|
||||
COPY --from=base /usr/local/bin/cargo-nextest /usr/local/bin/cargo-nextest
|
||||
|
||||
# The storkit binary
|
||||
COPY --from=base /usr/local/bin/storkit /usr/local/bin/storkit
|
||||
|
||||
# Copy the full source tree so rebuild_and_restart can do `cargo build`
|
||||
# from the workspace root (CARGO_MANIFEST_DIR is baked into the binary).
|
||||
# Alternative: mount the source as a volume.
|
||||
COPY --from=base /app /app
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
# ── Ports ────────────────────────────────────────────────────────────
|
||||
# Web UI + MCP server
|
||||
EXPOSE 3001
|
||||
|
||||
# ── Volumes (defined in docker-compose.yml) ──────────────────────────
|
||||
# /workspace – bind mount: target project repo
|
||||
# /root/.claude – named volume: Claude Code sessions/state
|
||||
# /usr/local/cargo/registry – named volume: cargo dependency cache
|
||||
|
||||
# ── Entrypoint ───────────────────────────────────────────────────────
|
||||
# Run storkit against the bind-mounted project at /workspace.
|
||||
# The server picks up ANTHROPIC_API_KEY from the environment.
|
||||
CMD ["storkit", "/workspace"]
|
||||
93
docker/docker-compose.yml
Normal file
93
docker/docker-compose.yml
Normal file
@@ -0,0 +1,93 @@
|
||||
# Story Kit – single-container deployment
|
||||
#
|
||||
# Usage:
|
||||
# # Set your API key and project path, then:
|
||||
# ANTHROPIC_API_KEY=sk-ant-... PROJECT_PATH=/path/to/your/repo \
|
||||
# docker compose -f docker/docker-compose.yml up
|
||||
#
|
||||
# OrbStack users: just install OrbStack and use `docker compose` normally.
|
||||
# OrbStack's VirtioFS bind mount driver is significantly faster than
|
||||
# Docker Desktop's default (see spike findings).
|
||||
|
||||
services:
|
||||
storkit:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
container_name: storkit
|
||||
ports:
|
||||
# Web UI + MCP endpoint
|
||||
- "3001:3001"
|
||||
environment:
|
||||
# Required: Anthropic API key for Claude Code agents
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:?Set ANTHROPIC_API_KEY}
|
||||
# Optional: override the server port (default 3001)
|
||||
- STORKIT_PORT=3001
|
||||
# Optional: Matrix bot credentials (if using Matrix integration)
|
||||
- MATRIX_HOMESERVER=${MATRIX_HOMESERVER:-}
|
||||
- MATRIX_USER=${MATRIX_USER:-}
|
||||
- MATRIX_PASSWORD=${MATRIX_PASSWORD:-}
|
||||
# Optional: Slack webhook (if using Slack integration)
|
||||
- SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN:-}
|
||||
- SLACK_APP_TOKEN=${SLACK_APP_TOKEN:-}
|
||||
volumes:
|
||||
# The target project repo – bind-mounted from host.
|
||||
# Changes made by agents inside the container are immediately
|
||||
# visible on the host (and vice versa).
|
||||
- ${PROJECT_PATH:?Set PROJECT_PATH}:/workspace
|
||||
|
||||
# Cargo registry cache – persists downloaded crates across
|
||||
# container restarts so `cargo build` doesn't re-download.
|
||||
- cargo-registry:/usr/local/cargo/registry
|
||||
|
||||
# Cargo git checkouts – persists git-based dependencies.
|
||||
- cargo-git:/usr/local/cargo/git
|
||||
|
||||
# Claude Code state – persists session history, projects config,
|
||||
# and conversation transcripts so --resume works across restarts.
|
||||
- claude-state:/root/.claude
|
||||
|
||||
# Storkit source tree for rebuild_and_restart.
|
||||
# The binary has CARGO_MANIFEST_DIR baked in at compile time
|
||||
# pointing to /app/server, so the source must be at /app.
|
||||
# This is COPY'd in the Dockerfile; mounting over it allows
|
||||
# live source updates without rebuilding the image.
|
||||
# Mount host source so rebuild_and_restart picks up live changes:
|
||||
- ./..:/app
|
||||
|
||||
# Keep cargo build artifacts off the bind mount.
|
||||
# Bind-mount directory traversal is ~23x slower than Docker volumes
|
||||
# (confirmed in spike 329). Cargo stat-checks every file in target/
|
||||
# on incremental builds — leaving it on the bind mount makes builds
|
||||
# catastrophically slow (~12s just to traverse the tree).
|
||||
- workspace-target:/workspace/target
|
||||
- storkit-target:/app/target
|
||||
|
||||
# Resource limits – cap the whole system.
|
||||
# Adjust based on your machine. These are conservative defaults.
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "4"
|
||||
memory: 8G
|
||||
reservations:
|
||||
cpus: "1"
|
||||
memory: 2G
|
||||
|
||||
# Health check – verify the MCP endpoint responds
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-sf", "http://localhost:3001/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Restart policy – restart on crash but not on manual stop
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
cargo-registry:
|
||||
cargo-git:
|
||||
claude-state:
|
||||
workspace-target:
|
||||
storkit-target:
|
||||
Reference in New Issue
Block a user