fix(channels): reply via reply_target and improve local Docker cache reuse

This commit is contained in:
Will Sarg 2026-02-17 09:22:01 -05:00
parent 9e0958dee5
commit b8bef379e2
4 changed files with 41 additions and 16 deletions

View file

@ -1,4 +1,4 @@
# syntax=docker/dockerfile:1
# syntax=docker/dockerfile:1.7
# ── Stage 1: Build ────────────────────────────────────────────
FROM rust:1.93-slim-trixie@sha256:9663b80a1621253d30b146454f903de48f0af925c967be48c84745537cd35d8b AS builder
@ -6,7 +6,9 @@ FROM rust:1.93-slim-trixie@sha256:9663b80a1621253d30b146454f903de48f0af925c967be
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y \
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
@ -14,19 +16,20 @@ RUN apt-get update && apt-get install -y \
COPY Cargo.toml Cargo.lock ./
# Create dummy main.rs to build dependencies
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
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 \
cargo build --release --locked
RUN rm -rf src
# 2. Copy source code
COPY . .
# Touch main.rs to force rebuild
RUN touch src/main.rs
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
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 \
cargo build --release --locked && \
strip target/release/zeroclaw
cp target/release/zeroclaw /app/zeroclaw && \
strip /app/zeroclaw
# ── Stage 2: Permissions & Config Prep ───────────────────────
FROM busybox:1.37@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f AS permissions
@ -35,7 +38,7 @@ 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'
RUN cat > /zeroclaw-data/.zeroclaw/config.toml <<EOF
workspace_dir = "/zeroclaw-data/workspace"
config_path = "/zeroclaw-data/.zeroclaw/config.toml"
api_key = ""
@ -65,7 +68,7 @@ RUN apt-get update && apt-get install -y \
&& rm -rf /var/lib/apt/lists/*
COPY --from=permissions /zeroclaw-data /zeroclaw-data
COPY --from=builder /app/target/release/zeroclaw /usr/local/bin/zeroclaw
COPY --from=builder /app/zeroclaw /usr/local/bin/zeroclaw
# Overwrite minimal config with DEV template (Ollama defaults)
COPY dev/config.template.toml /zeroclaw-data/.zeroclaw/config.toml
@ -92,7 +95,7 @@ CMD ["gateway", "--port", "3000", "--host", "[::]"]
# ── Stage 4: Production Runtime (Distroless) ─────────────────
FROM gcr.io/distroless/cc-debian13:nonroot@sha256:84fcd3c223b144b0cb6edc5ecc75641819842a9679a3a58fd6294bec47532bf7 AS release
COPY --from=builder /app/target/release/zeroclaw /usr/local/bin/zeroclaw
COPY --from=builder /app/zeroclaw /usr/local/bin/zeroclaw
COPY --from=permissions /zeroclaw-data /zeroclaw-data
# Environment setup

View file

@ -163,5 +163,7 @@ Note: local `deny` focuses on license/source policy; advisory scanning is handle
### Build cache notes
- Both `Dockerfile` and `dev/ci/Dockerfile` use BuildKit cache mounts for Cargo registry/git data.
- The root `Dockerfile` also caches Rust `target/` (`id=zeroclaw-target`) to speed repeat local image builds.
- Local CI reuses named Docker volumes for Cargo registry/git and target outputs.
- `./dev/ci.sh docker-smoke` and `./dev/ci.sh all` now use `docker buildx` local cache at `.cache/buildx-smoke` when available.
- The CI image keeps Rust toolchain defaults from `rust:1.92-slim` and installs pinned toolchain `1.92.0` (no custom `CARGO_HOME`/`RUSTUP_HOME` overrides), preventing repeated toolchain bootstrapping on each run.

View file

@ -11,12 +11,32 @@ else
fi
compose_cmd=(docker compose -f "$COMPOSE_FILE")
SMOKE_CACHE_DIR="${SMOKE_CACHE_DIR:-.cache/buildx-smoke}"
run_in_ci() {
local cmd="$1"
"${compose_cmd[@]}" run --rm local-ci bash -c "$cmd"
}
build_smoke_image() {
if docker buildx version >/dev/null 2>&1; then
mkdir -p "$SMOKE_CACHE_DIR"
local build_args=(
--load
--target dev
--cache-to "type=local,dest=$SMOKE_CACHE_DIR,mode=max"
-t zeroclaw-local-smoke:latest
.
)
if [ -f "$SMOKE_CACHE_DIR/index.json" ]; then
build_args=(--cache-from "type=local,src=$SMOKE_CACHE_DIR" "${build_args[@]}")
fi
docker buildx build "${build_args[@]}"
else
DOCKER_BUILDKIT=1 docker build --target dev -t zeroclaw-local-smoke:latest .
fi
}
print_help() {
cat <<'EOF'
ZeroClaw Local CI in Docker
@ -88,7 +108,7 @@ case "$1" in
;;
docker-smoke)
docker build --target dev -t zeroclaw-local-smoke:latest .
build_smoke_image
docker run --rm zeroclaw-local-smoke:latest --version
;;
@ -98,7 +118,7 @@ case "$1" in
run_in_ci "cargo build --release --locked --verbose"
run_in_ci "cargo deny check licenses sources"
run_in_ci "cargo audit"
docker build --target dev -t zeroclaw-local-smoke:latest .
build_smoke_image
docker run --rm zeroclaw-local-smoke:latest --version
;;

View file

@ -227,7 +227,7 @@ async fn process_channel_message(ctx: Arc<ChannelRuntimeContext>, msg: traits::C
truncate_with_ellipsis(&response, 80)
);
if let Some(channel) = target_channel.as_ref() {
if let Err(e) = channel.send(&response, &msg.channel).await {
if let Err(e) = channel.send(&response, &msg.reply_target).await {
eprintln!(" ❌ Failed to reply on {}: {e}", channel.name());
}
}