cf80bc7e97
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.
64 lines
2.6 KiB
Docker
64 lines
2.6 KiB
Docker
# 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"]
|