Dockerfile: cargo-chef + cargo cache mounts; drop manifest guard

This commit is contained in:
2026-10-26 04:49:21 +01:00
parent 01ea36bce9
commit 0486f4881f
5 changed files with 41 additions and 69 deletions

View File

@@ -6,67 +6,46 @@ RUN npm ci
COPY spa/ .
RUN npm run build
# ----- build -----
FROM rust:slim-bookworm AS builder
WORKDIR /build
# Cache dependency compilation separately from source
#
# Every workspace member's Cargo.toml must be listed here by hand — `cargo fetch`
# below reads the whole workspace graph, so a missing manifest fails the build with
# "failed to read .../Cargo.toml". Adding a crate to crates/ means adding a line here.
COPY Cargo.toml Cargo.lock ./
COPY .cargo ./.cargo
COPY crates/adapters/activitypub/Cargo.toml crates/adapters/activitypub/Cargo.toml
COPY crates/adapters/auth/Cargo.toml crates/adapters/auth/Cargo.toml
COPY crates/event-payload/Cargo.toml crates/event-payload/Cargo.toml
COPY crates/adapters/event-publisher/Cargo.toml crates/adapters/event-publisher/Cargo.toml
COPY crates/adapters/nats/Cargo.toml crates/adapters/nats/Cargo.toml
COPY crates/adapters/metadata/Cargo.toml crates/adapters/metadata/Cargo.toml
COPY crates/adapters/poster-fetcher/Cargo.toml crates/adapters/poster-fetcher/Cargo.toml
COPY crates/adapters/object-storage/Cargo.toml crates/adapters/object-storage/Cargo.toml
COPY crates/adapters/export/Cargo.toml crates/adapters/export/Cargo.toml
COPY crates/adapters/importer/Cargo.toml crates/adapters/importer/Cargo.toml
COPY crates/adapters/media-server/Cargo.toml crates/adapters/media-server/Cargo.toml
COPY crates/adapters/rss/Cargo.toml crates/adapters/rss/Cargo.toml
COPY crates/adapters/sqlite/Cargo.toml crates/adapters/sqlite/Cargo.toml
COPY crates/adapters/sqlite-federation/Cargo.toml crates/adapters/sqlite-federation/Cargo.toml
COPY crates/api-types/Cargo.toml crates/api-types/Cargo.toml
COPY crates/application/Cargo.toml crates/application/Cargo.toml
COPY crates/adapters/tmdb-enrichment/Cargo.toml crates/adapters/tmdb-enrichment/Cargo.toml
COPY crates/domain/Cargo.toml crates/domain/Cargo.toml
COPY crates/bootstrap/Cargo.toml crates/bootstrap/Cargo.toml
COPY crates/adapters/http-axum/Cargo.toml crates/adapters/http-axum/Cargo.toml
COPY crates/server/Cargo.toml crates/server/Cargo.toml
COPY crates/tui/Cargo.toml crates/tui/Cargo.toml
COPY crates/adapters/image-converter/Cargo.toml crates/adapters/image-converter/Cargo.toml
COPY crates/worker/Cargo.toml crates/worker/Cargo.toml
COPY crates/config/Cargo.toml crates/config/Cargo.toml
# Stub every crate so cargo can resolve and fetch deps
RUN find crates -name "Cargo.toml" | sed 's|/Cargo.toml||' | \
xargs -I{} sh -c 'mkdir -p {}/src && echo "fn main(){}" > {}/src/main.rs && echo "" > {}/src/lib.rs'
# ----- chef base -----
FROM rust:slim-bookworm AS chef
# libwebp-dev: required at build time by the `webp` crate (C bindings)
RUN apt-get update && apt-get install -y --no-install-recommends \
libwebp-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
RUN cargo install cargo-chef --locked --version 0.1.78
WORKDIR /build
RUN cargo fetch
# ----- planner: dependency recipe (changes only when manifests/lockfile change) -----
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
# Now copy real sources (invalidates cache only on source changes)
COPY crates ./crates
# ----- build -----
FROM chef AS builder
# All sqlx queries use the runtime API (no query! macros), so no database
# or .sqlx cache is needed at compile time.
#
# Features: federation (ActivityPub), nats (EVENT_BUS_BACKEND=nats).
# Build without federation: --build-arg FEATURES=
# To add NATS support: --build-arg FEATURES=federation,nats
# Declared before cook so cook and build compile identical feature sets.
ARG FEATURES=federation
RUN cargo build --release -p server -p worker --no-default-features --features "${FEATURES}"
# .cargo carries the registry config needed to fetch private crates
COPY .cargo ./.cargo
COPY --from=planner /build/recipe.json recipe.json
# target/ is a normal layer (no cache mount) so the cooked deps live in the image
# layer cache; only the registry/git download caches are mounted.
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,target=/usr/local/cargo/git,sharing=locked \
cargo chef cook --release -p server -p worker --no-default-features --features "${FEATURES}" --recipe-path recipe.json
# All sqlx queries use the runtime API (no query! macros), so no database
# or .sqlx cache is needed at compile time.
COPY Cargo.toml Cargo.lock ./
COPY crates ./crates
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,target=/usr/local/cargo/git,sharing=locked \
cargo build --release -p server -p worker --no-default-features --features "${FEATURES}"
# ----- runtime -----
FROM debian:bookworm-slim