Containerfile
⎇
Raw
1ARG RUST_VERSION=1.98
2ARG BUN_VERSION=1.4.2
3ARG TRUNK_VERSION=0.21.14
4ARG ALPINE_VERSION=3.24
5
6# ── build ────────────────────────────────────────────────────────────────────
7FROM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS build
8
9# re-declare the build-args: args set before FROM do not carry into stages
10ARG BUN_VERSION
11ARG TRUNK_VERSION
12
13# binaryen so trunk uses the system wasm-opt instead of downloading a glibc binary that cannot run on musl
14# openssl-dev + openssl-libs-static for webauthn-rs, whose core crate links
15# OpenSSL. The binary is static, so nothing is needed in the runtime image.
16# make builds jemalloc, the server's allocator.
17RUN apk add --no-cache curl ca-certificates musl-dev binaryen just make \
18 openssl-dev openssl-libs-static pkgconfig \
19 && rustup target add wasm32-unknown-unknown
20
21# bun
22COPY --from=oven/bun:${BUN_VERSION}-alpine /usr/local/bin/bun /usr/local/bin/bun
23
24# trunk
25RUN set -eux; \
26 url=https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-musl.tar.gz; \
27 curl -fsSL -o /tmp/trunk.tar.gz "${url}"; \
28 curl -fsSL "${url}.sha256" | awk '{print $1 " /tmp/trunk.tar.gz"}' | sha256sum -c -; \
29 tar xzf /tmp/trunk.tar.gz -C /usr/local/bin; \
30 rm -f /tmp/trunk.tar.gz
31
32WORKDIR /src
33COPY . /src
34
35# build
36RUN --mount=type=cache,target=/usr/local/cargo/registry \
37 --mount=type=cache,target=/src/target \
38 just build \
39 && cp target/release/dovenest /dovenest
40
41# ── prebuilt ─────────────────────────────────────────────────────────────────
42# CI has the binary already. It puts it at ci-bin/dovenest and selects
43# this stage with --build-arg BIN_STAGE=prebuilt. BuildKit and buildah do not
44# build a stage nobody references, so a normal build needs no ci-bin/.
45FROM scratch AS prebuilt
46COPY ci-bin/dovenest /dovenest
47
48# ── runtime ──────────────────────────────────────────────────────────────────
49FROM alpine:${ALPINE_VERSION}
50
51ARG BIN_STAGE=build
52
53# ffmpeg is only for video thumbnails, and it is most of the image: it pulls
54# ~120 MiB of codec libraries against 8 MiB for the rest
55RUN apk add --no-cache ca-certificates ffmpeg \
56 && mkdir -p /data /var/lib/dovenest /var/cache/dovenest
57
58COPY --from=${BIN_STAGE} /dovenest /usr/local/bin/dovenest
59
60EXPOSE 8080
61VOLUME ["/data", "/var/lib/dovenest"]
62
63HEALTHCHECK --interval=30s --start-period=10s --timeout=5s --retries=3 \
64 CMD wget -qO /dev/null http://127.0.0.1:8080/ || exit 1
65
66ENTRYPOINT ["/usr/local/bin/dovenest"]
67CMD ["--root", "/data", "--db", "/var/lib/dovenest/db.sqlite", "--bind", "0.0.0.0"]
68