feat: containerize doctate-server for minerva deployment
Multi-stage Dockerfile, host-network compose, idempotent deploy script. Configs and persistent data bind-mounted from /opt/stacks/doctate-server. deploy-server.sh handles bootstrap + re-deploy in one command with auto-prune (keep 5 last SHA-tagged images). See docs/deployment.md for bootstrap, rollback, and TLS-proxy notes.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
# Multi-stage build for doctate-server. Stage 1 compiles the Rust binary;
|
||||
# stage 2 ships only the binary + runtime tools (ffmpeg, hunspell dict).
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Stage 1: builder
|
||||
# -----------------------------------------------------------------------
|
||||
FROM rust:1.94-slim-bookworm AS builder
|
||||
|
||||
# pkg-config + ca-certificates suffice — reqwest uses rustls-tls
|
||||
# (no libssl-dev needed), and our other crates don't probe native libs.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
pkg-config ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
# Copy `common/` AND `server/` so the path dependency resolves
|
||||
# (server/Cargo.toml references `../common`).
|
||||
COPY common/ ./common/
|
||||
COPY server/ ./server/
|
||||
|
||||
WORKDIR /build/server
|
||||
# BuildKit cache mounts: registry/ and target/ persist between builds
|
||||
# but are NOT part of the resulting image layers. Output binaries
|
||||
# therefore have to be copied to /out (outside the cache mount) so
|
||||
# stage 2 can pick them up via COPY --from=builder.
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/build/server/target \
|
||||
cargo build --release --bin doctate-server --bin hash-password && \
|
||||
mkdir -p /out && \
|
||||
cp target/release/doctate-server /out/ && \
|
||||
cp target/release/hash-password /out/
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Stage 2: runtime
|
||||
# -----------------------------------------------------------------------
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
|
||||
# ffmpeg/ffprobe are invoked as subprocesses by server/src/transcribe/ffmpeg.rs.
|
||||
# hunspell-de-de installs the dict files /usr/share/hunspell/de_DE.{dic,aff}
|
||||
# which the `spellbook` Rust library reads via the HUNSPELL_DICT env var.
|
||||
# tzdata gives us proper local-time formatting in logs.
|
||||
# curl is required by HEALTHCHECK below.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ffmpeg hunspell-de-de ca-certificates curl tzdata && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /out/doctate-server /usr/local/bin/
|
||||
COPY --from=builder /out/hash-password /usr/local/bin/
|
||||
|
||||
# Default vocab ships with the image; operator can override via bind-mount.
|
||||
COPY server/vocab/ /app/vocab/
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
# Container-level health probe. SERVER_PORT defaults to 3000 if unset
|
||||
# (matches the value in server/.env.example).
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||
CMD curl -fsS "http://127.0.0.1:${SERVER_PORT:-3000}/api/health" || exit 1
|
||||
|
||||
CMD ["doctate-server"]
|
||||
Reference in New Issue
Block a user