# Built with `podman build` / `podman compose build` locally and Kaniko in
# CI. Stays Kaniko-clean: no `# syntax=docker/dockerfile:…` directive (Kaniko
# ignores it) and no BuildKit cache mounts (Kaniko unmounts them between
# RUN steps, so subsequent `cp` from the cached target/ would miss).
# ---------------------------------------------------------------------------
# Stage 1 — assets: compile Tailwind CSS, bundle JS, and stage FontAwesome webfonts.
# ---------------------------------------------------------------------------
FROM node:20-alpine AS assets
WORKDIR /app
# Install JS deps first so this layer caches across source changes.
COPY assets/package.json assets/package-lock.json ./assets/
RUN cd assets && npm ci --no-audit --no-fund
# Tailwind scans templates/ — bring it in too.
COPY assets/f ./assets/f
COPY templates ./templates
RUN cd assets \
&& ./node_modules/.bin/tailwindcss -i f/css/style.css -o f/css/app.css \
&& ./node_modules/.bin/esbuild f/js/src.js --bundle --minify --outfile=f/js/app.js \
&& mkdir -p f/webfonts \
&& cp node_modules/@fortawesome/fontawesome-free/webfonts/*.woff2 f/webfonts/ \
&& cp node_modules/@fortawesome/fontawesome-free/webfonts/*.ttf f/webfonts/
# ---------------------------------------------------------------------------
# Stage 2 — rust-builder: build all three binaries in release mode.
#
# Kept Kaniko-friendly: no BuildKit cache mounts (Kaniko unmounts them
# before subsequent steps, so cp-ing from a cached target/ would silently
# miss the binaries). Layer caching from the COPY ordering below
# (Cargo.toml/Cargo.lock first, then src) still helps local rebuilds.
# ---------------------------------------------------------------------------
FROM rust:1.98-bookworm AS rust-builder
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends pkg-config libssl-dev ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY Cargo.toml Cargo.lock build.rs ./
COPY migration/Cargo.toml migration/
COPY migration/src migration/src
COPY src src
COPY templates templates
# Tailwind output from stage 1 lives under assets/f — copy it in so build.rs
# (which embeds templates) and ServeDir at runtime have what they need.
COPY --from=assets /app/assets/f ./assets/f
RUN cargo build --release \
--bin webservice \
--bin queue-worker \
--bin registration-token \
--bin user-admin \
--bin backfill-previews \
&& mkdir -p /out \
&& cp target/release/webservice /out/ \
&& cp target/release/queue-worker /out/ \
&& cp target/release/registration-token /out/ \
&& cp target/release/user-admin /out/ \
&& cp target/release/backfill-previews /out/ \
&& rm -rf target
# ---------------------------------------------------------------------------
# Stage 3 — ocr-models: pre-fetch the ocrs detection + recognition .rten
# models so the OCR worker has them baked into the image. Stage is separate
# so the (slow) downloads cache independently from the cargo build.
#
# ADD rather than `RUN curl`: on the forge's BuildKit runner curl could not
# create its output file ("Permission denied", even in a freshly mkdir'd
# directory), while the builder fetching the URL itself needs no RUN step
# at all — and so no base image, apt or curl either.
#
# From the ocrs models' Hugging Face repo, pinned to a commit: a
# resolve/<commit>/ URL can't change under us. The S3 bucket ocrs used to
# point at has moved its files around — the .rten names now 403 (the
# bucket serves .onnx, which rten 0.21 can't load). These are the same
# published checkpoints, in the header-less .rten format (V1) rten reads.
# ---------------------------------------------------------------------------
FROM scratch AS ocr-models
ARG OCRS_MODELS=https://huggingface.co/robertknight/ocrs/resolve/df0edd170279ab971b53e094c627255a87e1a503
ADD --chmod=0644 ${OCRS_MODELS}/text-detection-ssfbcj81.rten /models/text-detection.rten
ADD --chmod=0644 ${OCRS_MODELS}/text-rec-checkpoint-s52qdbqt.rten /models/text-recognition.rten
# ---------------------------------------------------------------------------
# Stage 4 — runtime: minimal Debian slim with the binaries + assets + templates.
# ---------------------------------------------------------------------------
FROM debian:bookworm-slim AS runtime
# ffmpeg is here for the `poster` worker, which lifts a still frame out of a
# video so the image-only categorizers have something to read. It is the
# heaviest thing in this layer; drop it only if video uploads go away.
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates libssl3 ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd --system --gid 10001 dms \
&& useradd --system --uid 10001 --gid dms --home /app --shell /usr/sbin/nologin dms \
&& mkdir -p /app /data/storage /data/models \
&& chown -R dms:dms /app /data
WORKDIR /app
COPY --from=rust-builder /out/webservice /usr/local/bin/dms-webservice
COPY --from=rust-builder /out/queue-worker /usr/local/bin/dms-queue-worker
COPY --from=rust-builder /out/registration-token /usr/local/bin/dms-registration-token
COPY --from=rust-builder /out/user-admin /usr/local/bin/dms-user-admin
COPY --from=rust-builder /out/backfill-previews /usr/local/bin/dms-backfill-previews
COPY --from=assets /app/assets/f /app/assets/f
COPY --chown=dms:dms templates /app/templates
# OCR models bundled at a fixed image path — read-only and tied to the app
# version. Override via env if you swap to bigger/smaller models later.
COPY --from=ocr-models /models/text-detection.rten /opt/dms/models/text-detection.rten
COPY --from=ocr-models /models/text-recognition.rten /opt/dms/models/text-recognition.rten
USER dms
# Sensible defaults — override via `docker run -e ...` or compose.
ENV BIND_ADDRESS=0.0.0.0:3007 \
STORAGE_ROOT=/data/storage \
AUTO_MIGRATE=true \
REGISTRATION_ENABLED=false \
OCRS_DETECTION_MODEL=/opt/dms/models/text-detection.rten \
OCRS_RECOGNITION_MODEL=/opt/dms/models/text-recognition.rten
EXPOSE 3007
VOLUME ["/data"]
# `docker run … dms-webservice` → web (default)
# `docker run … dms-queue-worker --kind ocr` → categorizer
# `docker run … dms-registration-token …` → CLI
# `docker run … dms-user-admin …` → user management CLI
# `docker run … dms-backfill-previews` → queue grid previews for older videos/GIFs
CMD ["dms-webservice"]
⭐
Log in to mark this repository.
6.3 KiB · text
History
c20d4f7