# Build the SPA first so build.rs embeds web/dist via ARR_WEB_DIST. FROM node:22-bookworm-slim AS web WORKDIR /src ENV CI=true RUN corepack enable && corepack prepare pnpm@11.21.0 --activate COPY web/package.json web/pnpm-lock.yaml ./web/ RUN pnpm -C web install --frozen-lockfile --config.dangerouslyAllowAllBuilds=true COPY web ./web RUN pnpm -C web build # Every translation backend is a default-off cargo feature (DESIGN.md §15), so # a build without these ships an image that cannot translate at all. All four # go in: which one is in use is a database setting, and the point of the # feature switches is the build, not the deployment. # # The dependency build and the workspace build are split with cargo-chef so a # source-only change reuses the dependency layer. The two `cargo` invocations # must carry identical flags or the cook output is not reusable. FROM lukemathwalker/cargo-chef:latest-rust-1-bookworm AS chef WORKDIR /src ENV ARR_FEATURES=translate-openai,translate-deepl,translate-google,translate-command FROM chef AS planner COPY . . RUN cargo chef prepare --recipe-path recipe.json FROM chef AS build COPY --from=planner /src/recipe.json recipe.json # cargo-chef's skeleton keeps build scripts, and arr-daemon's panics in release # when it can find no SPA bundle. A stub satisfies it; the real bundle arrives # below and the changed ARR_WEB_DIST reruns only that one build script. RUN mkdir -p /stub/dist && printf 'stub\n' > /stub/dist/index.html ENV ARR_WEB_DIST=/stub/dist RUN cargo chef cook --release -p arr-daemon --features "$ARR_FEATURES" \ --recipe-path recipe.json COPY . . COPY --from=web /src/web/dist ./web/dist ENV ARR_WEB_DIST=/src/web/dist RUN cargo build --release -p arr-daemon --features "$ARR_FEATURES" # §15 runs `alass` over every fetched and every translated subtitle, and it is # not in Debian — a release binary is the only way in. Its own stage so the # runtime image needs no download tool, and so a source change does not refetch # it. The digest is pinned: an unverified binary from a release page is not # something to run over the library. The asset is x86-64 only, which is what # this image targets. FROM debian:bookworm-slim AS alass ARG ALASS_VERSION=2.0.0 ARG ALASS_SHA256=7bd0b9ae7e035d3ba940eacffb21243614df36231d47f21f0b4ce42001ab7fcd RUN apt-get update \ && apt-get install -y --no-install-recommends curl ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN curl -fsSL -o /usr/local/bin/alass \ "https://github.com/kaegi/alass/releases/download/v${ALASS_VERSION}/alass-linux64" \ && echo "${ALASS_SHA256} /usr/local/bin/alass" | sha256sum -c - \ && chmod +x /usr/local/bin/alass \ && alass --version FROM debian:bookworm-slim # ffmpeg covers both `ffprobe` for arr-probe and the audio extraction `alass` # shells out to. RUN apt-get update \ && apt-get install -y --no-install-recommends ffmpeg ca-certificates \ && rm -rf /var/lib/apt/lists/* COPY --from=alass /usr/local/bin/alass /usr/local/bin/alass COPY --from=build /src/target/release/arr /usr/local/bin/arr ENV ARR_BIND_ADDR=0.0.0.0:7878 \ ARR_DATABASE_PATH=/data/arr.db VOLUME /data EXPOSE 7878 ENTRYPOINT ["arr"]