fix(container): address all container anti-patterns (4.1–4.4)

- Replace broad COPY . . with targeted COPY src/ and firmware/ to
  preserve Docker layer cache across non-build file changes (4.1)
- Inline permissions/config prep into builder stage, removing the
  extra busybox stage and its maintenance/security overhead (4.2)
- Strip heavy dev tools (vim, git, iputils-ping, openssl) from dev
  image, keeping only ca-certificates and curl (4.3)
- Replace expensive zeroclaw doctor healthcheck with lightweight
  zeroclaw status; increase interval from 30s to 60s (4.4)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Alex Gorevski 2026-02-17 10:06:35 -08:00 committed by Chummy
parent 9e9a4a53ab
commit da326b265d
2 changed files with 16 additions and 24 deletions

View file

@ -24,8 +24,9 @@ RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/regist
cargo build --release --locked
RUN rm -rf src benches
# 2. Copy source code
COPY . .
# 2. Copy only build-relevant source paths (avoid cache-busting on docs/tests/scripts)
COPY src/ src/
COPY firmware/ firmware/
RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,id=zeroclaw-cargo-git,target=/usr/local/cargo/git,sharing=locked \
--mount=type=cache,id=zeroclaw-target,target=/app/target,sharing=locked \
@ -33,14 +34,10 @@ RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/regist
cp target/release/zeroclaw /app/zeroclaw && \
strip /app/zeroclaw
# ── Stage 2: Permissions & Config Prep ───────────────────────
FROM busybox:1.37@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f AS permissions
# Create directory structure (simplified workspace path)
RUN mkdir -p /zeroclaw-data/.zeroclaw /zeroclaw-data/workspace
# Create minimal config for PRODUCTION (allows binding to public interfaces)
# NOTE: Provider configuration must be done via environment variables at runtime
RUN cat > /zeroclaw-data/.zeroclaw/config.toml <<EOF
# Prepare runtime directory structure and default config inline (no extra stage)
RUN mkdir -p /zeroclaw-data/.zeroclaw /zeroclaw-data/workspace && \
cat > /zeroclaw-data/.zeroclaw/config.toml <<EOF && \
chown -R 65534:65534 /zeroclaw-data
workspace_dir = "/zeroclaw-data/workspace"
config_path = "/zeroclaw-data/.zeroclaw/config.toml"
api_key = ""
@ -54,22 +51,16 @@ host = "[::]"
allow_public_bind = true
EOF
RUN chown -R 65534:65534 /zeroclaw-data
# ── Stage 3: Development Runtime (Debian) ────────────────────
# ── Stage 2: Development Runtime (Debian) ────────────────────
FROM debian:trixie-slim@sha256:f6e2cfac5cf956ea044b4bd75e6397b4372ad88fe00908045e9a0d21712ae3ba AS dev
# Install runtime dependencies + basic debug tools
# Install essential runtime dependencies only (use docker-compose.override.yml for dev tools)
RUN apt-get update && apt-get install -y \
ca-certificates \
openssl \
curl \
git \
iputils-ping \
vim \
&& rm -rf /var/lib/apt/lists/*
COPY --from=permissions /zeroclaw-data /zeroclaw-data
COPY --from=builder /zeroclaw-data /zeroclaw-data
COPY --from=builder /app/zeroclaw /usr/local/bin/zeroclaw
# Overwrite minimal config with DEV template (Ollama defaults)
@ -94,11 +85,11 @@ EXPOSE 3000
ENTRYPOINT ["zeroclaw"]
CMD ["gateway"]
# ── Stage 4: Production Runtime (Distroless) ─────────────────
# ── Stage 3: Production Runtime (Distroless) ─────────────────
FROM gcr.io/distroless/cc-debian13:nonroot@sha256:84fcd3c223b144b0cb6edc5ecc75641819842a9679a3a58fd6294bec47532bf7 AS release
COPY --from=builder /app/zeroclaw /usr/local/bin/zeroclaw
COPY --from=permissions /zeroclaw-data /zeroclaw-data
COPY --from=builder /zeroclaw-data /zeroclaw-data
# Environment setup
ENV ZEROCLAW_WORKSPACE=/zeroclaw-data/workspace

View file

@ -49,10 +49,11 @@ services:
cpus: '0.5'
memory: 512M
# Health check
# Health check — uses lightweight status instead of full diagnostics.
# For images with curl, prefer: curl -f http://localhost:3000/health
healthcheck:
test: ["CMD", "zeroclaw", "doctor"]
interval: 30s
test: ["CMD", "zeroclaw", "status"]
interval: 60s
timeout: 10s
retries: 3
start_period: 10s