# ============================================================ # ZCLAW SaaS Backend - Multi-stage Docker Build # ============================================================ # Build: docker build -t zclaw-saas . # Run: docker run --env-file saas-env.example zclaw-saas # ============================================================ # # .dockerignore recommended contents: # target/ # node_modules/ # desktop/ # admin/ # admin-v2/ # docs/ # .git/ # .claude/ # *.md # *.pen # plans/ # dist/ # pencil-new.pen # ============================================================ # ---- Stage 1: Build ---- FROM rust:1.85-bookworm AS builder WORKDIR /usr/src/zclaw # Cache dependency builds by copying manifests first COPY Cargo.toml Cargo.lock ./ # Create dummy lib.rs files so cargo can resolve the workspace RUN mkdir -p crates/zclaw-types/src && echo "" > crates/zclaw-types/src/lib.rs RUN mkdir -p crates/zclaw-memory/src && echo "" > crates/zclaw-memory/src/lib.rs RUN mkdir -p crates/zclaw-runtime/src && echo "" > crates/zclaw-runtime/src/lib.rs RUN mkdir -p crates/zclaw-kernel/src && echo "" > crates/zclaw-kernel/src/lib.rs RUN mkdir -p crates/zclaw-skills/src && echo "" > crates/zclaw-skills/src/lib.rs RUN mkdir -p crates/zclaw-hands/src && echo "" > crates/zclaw-hands/src/lib.rs RUN mkdir -p crates/zclaw-protocols/src && echo "" > crates/zclaw-protocols/src/lib.rs RUN mkdir -p crates/zclaw-pipeline/src && echo "" > crates/zclaw-pipeline/src/lib.rs RUN mkdir -p crates/zclaw-growth/src && echo "" > crates/zclaw-growth/src/lib.rs RUN mkdir -p crates/zclaw-saas/src && echo "fn main() {}" > crates/zclaw-saas/src/main.rs RUN mkdir -p desktop/src-tauri/src && echo "" > desktop/src-tauri/src/lib.rs # Copy all crate Cargo.toml files for dependency resolution COPY crates/zclaw-types/Cargo.toml crates/zclaw-types/Cargo.toml COPY crates/zclaw-memory/Cargo.toml crates/zclaw-memory/Cargo.toml COPY crates/zclaw-runtime/Cargo.toml crates/zclaw-runtime/Cargo.toml COPY crates/zclaw-kernel/Cargo.toml crates/zclaw-kernel/Cargo.toml COPY crates/zclaw-skills/Cargo.toml crates/zclaw-skills/Cargo.toml COPY crates/zclaw-hands/Cargo.toml crates/zclaw-hands/Cargo.toml COPY crates/zclaw-protocols/Cargo.toml crates/zclaw-protocols/Cargo.toml COPY crates/zclaw-pipeline/Cargo.toml crates/zclaw-pipeline/Cargo.toml COPY crates/zclaw-growth/Cargo.toml crates/zclaw-growth/Cargo.toml COPY crates/zclaw-saas/Cargo.toml crates/zclaw-saas/Cargo.toml COPY desktop/src-tauri/Cargo.toml desktop/src-tauri/Cargo.toml # Build dependencies only (cached layer) RUN cargo build --release -p zclaw-saas 2>/dev/null || true # Now copy the actual source code COPY crates/ crates/ COPY desktop/src-tauri/src/ desktop/src-tauri/src/ # Touch source files to invalidate cache after dependency layer RUN find crates/zclaw-saas/src -type f -exec touch {} + # Build the final binary RUN cargo build --release -p zclaw-saas # ---- Stage 2: Runtime ---- FROM debian:bookworm-slim # Install runtime dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates \ curl \ && rm -rf /var/lib/apt/lists/* # Create non-root user for security RUN groupadd --gid 1000 zclaw && \ useradd --uid 1000 --gid zclaw --shell /bin/bash --create-home zclaw WORKDIR /app # Copy binary from builder COPY --from=builder /usr/src/zclaw/target/release/zclaw-saas ./zclaw-saas # Copy default config (can be overridden by env vars) COPY saas-config.toml ./saas-config.toml # Set ownership RUN chown -R zclaw:zclaw /app # Switch to non-root user USER zclaw # Expose SaaS backend port EXPOSE 8080 # Health check HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 ENTRYPOINT ["./zclaw-saas"]