39b1964b68
Tests that create temp git repos produce thousands of lines of "Using 'master' as the name for the initial branch" hints that bury actual test failures in agent output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
134 lines
6.1 KiB
Docker
134 lines
6.1 KiB
Docker
# Huskies – 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 huskies -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
|
||
|
||
# Clippy and rustfmt are needed at runtime for acceptance gates
|
||
RUN rustup component add clippy rustfmt
|
||
|
||
# ── 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
|
||
|
||
# ── Working directory ────────────────────────────────────────────────
|
||
# /app holds the huskies 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 huskies 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/huskies /usr/local/bin/huskies
|
||
|
||
# ── 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 \
|
||
# procps provides ps, needed by tests and process management
|
||
procps \
|
||
&& 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 huskies binary
|
||
COPY --from=base /usr/local/bin/huskies /usr/local/bin/huskies
|
||
|
||
# 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
|
||
|
||
# ── Non-root user ────────────────────────────────────────────────────
|
||
# Claude Code refuses --dangerously-skip-permissions (bypassPermissions)
|
||
# when running as root. Create a dedicated user so agents can launch.
|
||
RUN groupadd -r huskies \
|
||
&& useradd -r -g huskies -m -d /home/huskies huskies \
|
||
&& mkdir -p /home/huskies/.claude \
|
||
&& chown -R huskies:huskies /home/huskies \
|
||
&& chown -R huskies:huskies /usr/local/cargo /usr/local/rustup \
|
||
&& chown -R huskies:huskies /app \
|
||
&& mkdir -p /workspace/target /app/target \
|
||
&& chown huskies:huskies /workspace/target /app/target \
|
||
&& git config --global init.defaultBranch master
|
||
|
||
# ── Entrypoint ───────────────────────────────────────────────────────
|
||
# Validates required env vars (GIT_USER_NAME, GIT_USER_EMAIL) and
|
||
# configures git identity before starting the server.
|
||
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||
|
||
USER huskies
|
||
WORKDIR /workspace
|
||
|
||
# ── Ports ────────────────────────────────────────────────────────────
|
||
# Web UI + MCP server
|
||
EXPOSE 3001
|
||
|
||
# ── Volumes (defined in docker-compose.yml) ──────────────────────────
|
||
# /workspace – bind mount: target project repo
|
||
# /home/huskies/.claude – named volume: Claude Code sessions/state
|
||
# /usr/local/cargo/registry – named volume: cargo dependency cache
|
||
|
||
ENTRYPOINT ["entrypoint.sh"]
|
||
CMD ["huskies", "/workspace"]
|