Files
kvitt/server/Dockerfile
T
jacobh2 06f48ef9e9 M2a: server workspace, kvitt-domain, skeleton routes, OpenAPI match, Dockerfile
Cargo workspace (kvitt-domain, kvitt-server, kvitt-import), Rust 1.99.1 pinned.
kvitt-domain passes every Rust vector and adds next_occurrence_date (D-015).
kvitt-server: config, SQLite pool (WAL, §8.9 pragmas), migration 0001 identical to
the contract schema, error type for all 25 codes, auth extractor and protocol
layer, all 33 routes (E-1/E-2 implemented, the rest 501), utoipa document equal
to contracts/openapi.yaml, seams for M3/M4/M9, serve/migrate/healthcheck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:30:20 +02:00

38 lines
2.1 KiB
Docker

# Kvitt server image (SPEC §10.3). Build context: server/. Built on the owner's M4 Mac, never on the Pi:
# docker build --platform linux/arm64 -f server/Dockerfile -t kvitt-server:dev server/
# linux/amd64 builds the same way (--platform linux/amd64; emulated on the Mac, slow). The Rust version is the one
# pinned in rust-toolchain.toml; the two always change together.
# ---- stage 1: build --------------------------------------------------------------------------------------------
FROM docker.io/library/rust:1.99.1-bookworm AS build
ARG TARGETARCH
# Use the image's toolchain as is; rust-toolchain.toml names the same version but would also pull clippy/rustfmt.
ENV RUSTUP_TOOLCHAIN=1.99.1 \
CARGO_TERM_COLOR=never
WORKDIR /src
COPY . .
# Native build for the target platform: aarch64-unknown-linux-gnu on arm64 (generic Armv8-A, no
# target-cpu=native: the Pi 3 is a Cortex-A53), x86_64-unknown-linux-gnu on amd64.
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/src/target,id=kvitt-target-${TARGETARCH} \
case "${TARGETARCH:-arm64}" in \
arm64) triple=aarch64-unknown-linux-gnu ;; \
amd64) triple=x86_64-unknown-linux-gnu ;; \
*) echo "unsupported TARGETARCH ${TARGETARCH}" >&2; exit 1 ;; \
esac \
&& cargo build --release --locked --target "$triple" -p kvitt-server -p kvitt-import \
&& mkdir -p /out \
&& cp "target/$triple/release/kvitt-server" "target/$triple/release/kvitt-import" /out/
# ---- stage 2: runtime ------------------------------------------------------------------------------------------
# glibc + libgcc, no shell, no package manager. Pinned by digest (multi-arch index of :nonroot).
FROM gcr.io/distroless/cc-debian12:nonroot@sha256:9dac0a79194e45a7da0158a9c6da57b217585af0786db3845d1f0ec1a0dd182f
COPY --from=build /out/kvitt-server /out/kvitt-import /usr/local/bin/
# Runs as uid/gid 10001 with a read-only root filesystem; /data is the only writable volume and /secrets is
# mounted read-only (SPEC §8.9). Listens on 8080 inside the compose network.
USER 10001:10001
ENV KVITT_DATA_DIR=/data
EXPOSE 8080
ENTRYPOINT ["kvitt-server"]
CMD ["serve"]