Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
8-task cluster completion bringing 3-replica StatefulSet from isolated nodes to fully functional cluster: 1. Fix Gateway /metrics 500 (wire PrometheusHandle) 2. gRPC server + SWIM background tasks (probe, suspicion, gossip dissemination) 3. join() registers peers in membership table via PingResponse fields 4. Shard rebalancing on membership changes (deterministic round-robin) 5. API cluster wiring (DNS resolution, Gateway, gRPC, gossip broadcaster) 6. Single binary merge (stemedb-api --features cluster replaces stemedb-node) 7. Auth header forwarding (X-API-Key passed through Gateway to backends) 8. CORS restriction (STEMEDB_ALLOWED_ORIGINS env var, permissive fallback)
80 lines
3.0 KiB
Docker
80 lines
3.0 KiB
Docker
# StemeDB API Docker Build
|
|
#
|
|
# Four-stage build using cargo-chef for efficient dependency caching:
|
|
# chef -> base image with cargo-chef installed
|
|
# planner -> generate recipe.json (cache key for deps)
|
|
# cacher -> compile dependencies only (cached until Cargo.lock changes)
|
|
# builder -> compile service binary using cached deps (FROM cacher)
|
|
# runtime -> minimal image: stripped binary, non-root user, no dev tools
|
|
#
|
|
# Cache behavior:
|
|
# - Cold build: ~15-20 min (deps + binary)
|
|
# - Warm build (source-only change): ~2-5 min (deps cached, binary only)
|
|
# - Dep change: full rebuild of cacher + builder (~15-20 min)
|
|
|
|
# Stage 0: Base image with cargo-chef installed
|
|
# Cached independently — only rebuilds when the chef version pin changes.
|
|
FROM rust:bookworm AS chef
|
|
RUN cargo install cargo-chef --locked
|
|
WORKDIR /app
|
|
|
|
# Stage 1: Planner — generate recipe.json from workspace manifests
|
|
# COPY . . is intentional: cargo chef prepare only reads Cargo.toml files.
|
|
# BuildKit content-addresses recipe.json, so the cacher layer stays cached
|
|
# even if this stage rebuilds due to a .rs source change.
|
|
FROM chef AS planner
|
|
COPY . .
|
|
RUN cargo chef prepare --recipe-path recipe.json
|
|
|
|
# Stage 2: Cacher — compile dependencies only
|
|
# This layer is invalidated only when Cargo.toml or Cargo.lock changes.
|
|
# protobuf-compiler is required by stemedb-rpc/build.rs (compiles sync.proto).
|
|
FROM chef AS cacher
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends protobuf-compiler && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
COPY --from=planner /app/recipe.json recipe.json
|
|
# Proto files must be present for stemedb-rpc/build.rs to run during dep compilation
|
|
COPY crates/stemedb-rpc/proto/ crates/stemedb-rpc/proto/
|
|
RUN cargo chef cook --release --recipe-path recipe.json
|
|
|
|
# Stage 3: Builder — compile the service binary using cached deps
|
|
# Inherits compiled deps from cacher; only workspace source is compiled here.
|
|
FROM cacher AS builder
|
|
COPY . .
|
|
RUN cargo build --release -p stemedb-api --features cluster
|
|
# Strip debug symbols before copying to runtime image
|
|
RUN strip target/release/stemedb-api
|
|
|
|
# Stage 4: Runtime — minimal production image
|
|
FROM debian:bookworm-slim AS runtime
|
|
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
ca-certificates \
|
|
curl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Non-root user for security
|
|
RUN useradd --system --no-create-home --shell /bin/false stemedb
|
|
|
|
COPY --from=builder /app/target/release/stemedb-api /usr/local/bin/stemedb-api
|
|
COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
|
|
RUN chmod +x /usr/local/bin/entrypoint.sh && \
|
|
mkdir -p /data/wal /data/db && chown -R stemedb:stemedb /data
|
|
|
|
USER stemedb
|
|
|
|
ENV STEMEDB_WAL_DIR=/data/wal \
|
|
STEMEDB_DB_DIR=/data/db \
|
|
STEMEDB_BIND_ADDR=0.0.0.0:18180 \
|
|
RUST_LOG=stemedb_api=info,stemedb_cluster=info
|
|
|
|
EXPOSE 18180 18181 18182 18183
|
|
|
|
HEALTHCHECK --interval=5s --timeout=3s --start-period=15s --retries=3 \
|
|
CMD curl -f http://localhost:18180/v1/health || exit 1
|
|
|
|
ENTRYPOINT ["entrypoint.sh"]
|