# 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 tidal/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 <subcommand>`
# 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"]
