ARG RUST_VERSION=1.98 ARG BUN_VERSION=1.4.2 ARG TRUNK_VERSION=0.21.14 ARG ALPINE_VERSION=3.24 # ── build ──────────────────────────────────────────────────────────────────── FROM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS build # re-declare the build-args: args set before FROM do not carry into stages ARG BUN_VERSION ARG TRUNK_VERSION # binaryen so trunk uses the system wasm-opt instead of downloading a glibc binary that cannot run on musl # openssl-dev + openssl-libs-static for webauthn-rs, whose core crate links # OpenSSL. The binary is static, so nothing is needed in the runtime image. RUN apk add --no-cache curl ca-certificates musl-dev binaryen just \ openssl-dev openssl-libs-static pkgconfig \ && rustup target add wasm32-unknown-unknown # bun COPY --from=oven/bun:${BUN_VERSION}-alpine /usr/local/bin/bun /usr/local/bin/bun # trunk RUN set -eux; \ url=https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-musl.tar.gz; \ curl -fsSL -o /tmp/trunk.tar.gz "${url}"; \ curl -fsSL "${url}.sha256" | awk '{print $1 " /tmp/trunk.tar.gz"}' | sha256sum -c -; \ tar xzf /tmp/trunk.tar.gz -C /usr/local/bin; \ rm -f /tmp/trunk.tar.gz WORKDIR /src COPY . /src # build RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/src/target \ just build \ && cp target/release/filebrowser-ng /filebrowser-ng # ── prebuilt ───────────────────────────────────────────────────────────────── # CI has the binary already. It puts it at ci-bin/filebrowser-ng and selects # this stage with --build-arg BIN_STAGE=prebuilt. BuildKit and buildah do not # build a stage nobody references, so a normal build needs no ci-bin/. FROM scratch AS prebuilt COPY ci-bin/filebrowser-ng /filebrowser-ng # ── runtime ────────────────────────────────────────────────────────────────── FROM alpine:${ALPINE_VERSION} ARG BIN_STAGE=build # ffmpeg is only for video thumbnails, and it is most of the image: it pulls # ~120 MiB of codec libraries against 8 MiB for the rest RUN apk add --no-cache ca-certificates ffmpeg \ && mkdir -p /data /var/lib/filebrowser /var/cache/filebrowser COPY --from=${BIN_STAGE} /filebrowser-ng /usr/local/bin/filebrowser-ng EXPOSE 8080 VOLUME ["/data", "/var/lib/filebrowser"] HEALTHCHECK --interval=30s --start-period=10s --timeout=5s --retries=3 \ CMD wget -qO /dev/null http://127.0.0.1:8080/ || exit 1 ENTRYPOINT ["/usr/local/bin/filebrowser-ng"] CMD ["--root", "/data", "--db", "/var/lib/filebrowser/db.sqlite", "--bind", "0.0.0.0"]