# Multi-region tidalDB cluster image. # # Runs a 3-region cluster (us-east, eu-west, ap-south) behind a single HTTP # surface on port 9500. Regions replicate over the real tidal-net gRPC transport # (loopback), but all run in this single container process — there is no host or # process isolation, so it is NOT production HA (true multi-process deployment is # m8p10). See docs/runbooks/cluster.md for the operational API. # # Build context is this repository's root (the workspace `Cargo.toml` / # `Cargo.lock` and every member crate live there). Build from the repo root: # # docker build -f docker/cluster/Dockerfile -t tidaldb:cluster . # # The repo-root allowlist `.dockerignore` strips target/, node_modules/, .git, # and .env* from the context, so `COPY . .` brings in exactly the workspace # sources cargo needs to resolve the member graph and build `-p tidal-server`. # Pin the builder to bookworm so its glibc matches the bookworm-slim runtime # below. The default `rust:1.91` tracks Debian trixie (glibc 2.41), whose # auto-vectorized math pulls in `libmvec.so.1` — a library bookworm's glibc does # not ship, so a trixie-built binary aborts at startup on bookworm with # "libmvec.so.1: cannot open shared object file". FROM rust:1.91-bookworm AS builder ARG DEBIAN_FRONTEND=noninteractive WORKDIR /app # Copy the full workspace and build only the server binary. The unified # workspace requires every member manifest present to resolve metadata, so we # copy the whole (already-pruned) context rather than a fragile manifest-only # subset. COPY . . # g++ builds the usearch C++ HNSW core; protobuf-compiler (protoc) is needed by # tidal-net's build script (tonic-build compiles the WAL-shipping .proto), which # tidal-server now depends on for real gRPC cluster replication. RUN apt-get update && apt-get install -y --no-install-recommends g++ protobuf-compiler && rm -rf /var/lib/apt/lists/* RUN cargo build -p tidal-server --release --locked FROM debian:bookworm-slim ARG DEBIAN_FRONTEND=noninteractive WORKDIR /srv RUN useradd --system --home /srv tidal && \ apt-get update && apt-get install -y --no-install-recommends ca-certificates curl && \ rm -rf /var/lib/apt/lists/* COPY --from=builder /app/target/release/tidal-server /usr/local/bin/tidal-server COPY --chown=tidal:tidal tidal-server/config /etc/tidal-server USER tidal EXPOSE 9500 # Path the server reads its schema/topology from. The binary-side clap wiring # for this lives in tidal-server (see sibling task T5); keep the name and # default in sync with it here. ENV TIDAL_CONFIG=/etc/tidal-server # Cluster mode is gated as experimental: replication is real gRPC but all # regions share one process (no host/process isolation), so it refuses to start # without an explicit opt-in. The image opts in here so `docker run` works; the # server still logs a loud WARN that this is not production HA. ENV TIDAL_ALLOW_EXPERIMENTAL_CLUSTER=1 HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ CMD curl -f http://localhost:9500/health || exit 1 # ENTRYPOINT is just the binary so `docker run tidaldb:cluster ` # overrides work. CMD carries the default cluster invocation against the baked # schema + topology. ENTRYPOINT ["tidal-server"] CMD ["cluster", "--listen", "0.0.0.0:9500", "--schema", "/etc/tidal-server/default-schema.yaml", "--topology", "/etc/tidal-server/default-cluster.yaml"]