diff --git a/Dockerfile b/Dockerfile index bd385ab..7f37883 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,12 +16,48 @@ COPY . . # no libc. Trim symbols/DWARF to shrink the layer. RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags='-s -w' -o /out/tapir ./cmd/tapir +# ── ffmpeg ────────────────────────────────────────────────────────────────── +# Audio upload probes files with ffprobe and converts them with ffmpeg (ADR-033, +# #34 option A). Static builds, so they run in the distroless image below. +# +# Pinned by version AND sha256: a changed upstream file fails the build instead of +# shipping. The checksum proves these are the bytes that were reviewed (2026-10-02; +# the publisher's md5 matched too). It does NOT prove authenticity: the publisher +# signs nothing we can check. amd64 only (the cluster is one amd64 node). +# +# These builds are GPLv3 (--enable-gpl --enable-version3). The service is private and +# the image is not distributed; the licence text is copied into the image anyway. +# +# The release URL moves on when upstream releases a newer version, so the pinned +# version is tried in releases/ and then old-releases/. If neither has it the build +# fails; vendoring the verified tarball is the durable fix. +FROM golang:1.26 AS ffmpeg + +ARG FFMPEG_VERSION=7.0.2 +ARG FFMPEG_SHA256=abda8d77ce8309141f83ab8edf0596834087c52467f6badf376a6a2a4c87cf67 + +RUN set -eu; \ + mkdir -p /out; \ + for dir in releases old-releases; do \ + curl -fsSL -o /out/ffmpeg.tar.xz "https://johnvansickle.com/ffmpeg/${dir}/ffmpeg-${FFMPEG_VERSION}-amd64-static.tar.xz" && break; \ + done; \ + echo "${FFMPEG_SHA256} /out/ffmpeg.tar.xz" | sha256sum -c -; \ + tar -xJf /out/ffmpeg.tar.xz -C /out --strip-components=1 --wildcards '*/ffmpeg' '*/ffprobe' '*/GPLv3.txt'; \ + rm /out/ffmpeg.tar.xz + # ── runtime ───────────────────────────────────────────────────────────────── # distroless static + nonroot: no shell, no package manager, runs as uid 65532. # ca-certificates are bundled, which the OIDC/HTTPS clients need. FROM gcr.io/distroless/static-debian12:nonroot COPY --from=build /out/tapir /tapir +COPY --from=ffmpeg /out/ffmpeg /out/ffprobe /usr/local/bin/ +COPY --from=ffmpeg /out/GPLv3.txt /usr/share/doc/ffmpeg/GPLv3.txt + +# Where the service finds them. Uploads stay OFF until TAPIR_UPLOADS_ENABLED is set +# (a deployment decision, not an image one). +ENV TAPIR_FFMPEG_BIN=/usr/local/bin/ffmpeg \ + TAPIR_FFPROBE_BIN=/usr/local/bin/ffprobe EXPOSE 8080 USER nonroot:nonroot