stemedb/Dockerfile
jordan d36de85bec
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
feat: cluster deployment — build both stemedb-api and stemedb-node binaries
- Dockerfile: build stemedb-api + stemedb-node, add entrypoint.sh
- entrypoint.sh: runs both binaries when STEMEDB_CLUSTER_MODE=true
- Woodpecker: deploy to StatefulSet instead of Deployment
2026-03-07 01:07:09 -07:00

81 lines
3.1 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 -p stemedb-cluster
# Strip debug symbols before copying to runtime image
RUN strip target/release/stemedb-api target/release/stemedb-node
# 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 --from=builder /app/target/release/stemedb-node /usr/local/bin/stemedb-node
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"]