Ctrl K
ComunidadGuías…

Dockerfile.nvenc

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# ============================================================================
# Shrinkerr — GPU / NVENC variant.
#
# Runs on:
#   - linux/amd64 ONLY (nvidia/cuda:* base image has no arm64 variant)
#
# Encoding: NVENC (hardware) via ffmpeg's hevc_nvenc, with libx265 CPU fallback.
# Requires: an NVIDIA GPU + the NVIDIA Container Toolkit on the host.
#
# If you don't have an NVIDIA GPU (or you're on Mac, Pi, etc.), use the
# portable multi-arch image built from the default `Dockerfile` instead:
#   ghcr.io/<owner>/shrinkerr:latest
# ============================================================================

# Stage 1: Build frontend
FROM mirror.gcr.io/library/node:20-slim AS frontend-build
WORKDIR /app/frontend
COPY frontend/package.json frontend/package-lock.json* ./
RUN npm ci
COPY frontend/ ./
RUN npm run build

# Stage 2: Runtime — CUDA base image, x86_64 only.
# v0.5.13: bumped from cuda:12.3.1-runtime-ubuntu22.04 to
# cuda:12.6.3-runtime-ubuntu24.04 for the lower CVE count Ubuntu 24.04
# carries vs 22.04. CUDA 12.6's driver floor is the same 525.60.13+ as
# 12.3, so existing users don't need to upgrade their NVIDIA driver.
# Ubuntu 24.04 ships Python 3.12 by default (3.11 was 22.04's default),
# so the apt-get install list below moves to python3.12 too.
# v0.7.4: pulled from NVIDIA's own registry (nvcr.io) instead of docker.io
# to keep the NVENC build off the Docker Hub rate-limit path. Same image,
# different host. See the CPU Dockerfile for the matching mirror.gcr.io
# swap on the python/node base images.
# v0.9.81: switched runtime -> cudnn-runtime so CTranslate2 (faster-whisper's
# engine) can run audio language detection on the GPU. CTranslate2 4.5+ (we
# ship 4.8.1) needs cuDNN 9, which this image carries; the plain -runtime
# image has none, so whisper silently fell back to CPU. device="auto" still
# falls back to CPU when no GPU/cuDNN is present, so nothing else changes.
FROM nvcr.io/nvidia/cuda:12.6.3-cudnn-runtime-ubuntu24.04

# Install Python, curl, and GPG for repo signing.
#
# VA-API runtime is also baked in here so users with a mixed Intel iGPU
# + NVIDIA dGPU host (e.g. NUC9 + Quadro) can pick `qsv` / `vaapi` /
# `nvenc` as needed in Settings → Encoding. Harmless on hosts without
# Intel/AMD graphics — ffmpeg simply doesn't surface those encoders.
# v0.3.67+. See the base Dockerfile for the rationale.
RUN set -eux; \
    apt-get update; \
    # v0.5.13: pull latest security patches at build time. Same
    # rationale as the CPU Dockerfile — cheap, knocks down the bulk
    # of Scout-reported CVEs without changing the base image.
    apt-get upgrade -y --no-install-recommends; \
    apt-get install -y --no-install-recommends \
        python3.12 python3.12-venv python3-pip \
        curl xz-utils \
        libarchive-tools \
        libbluray-bin \
        mkvtoolnix \
        tesseract-ocr \
        tesseract-ocr-eng tesseract-ocr-chi-sim tesseract-ocr-chi-tra \
        tesseract-ocr-jpn tesseract-ocr-kor tesseract-ocr-rus tesseract-ocr-ara \
        libgl1 libglib2.0-0 \
        libva-drm2 \
        intel-media-va-driver-non-free \
        i965-va-driver \
        mesa-va-drivers \
        vainfo \
        libvpl2 libmfx1 \
        build-essential cmake meson ninja-build pkg-config \
        libdrm-dev libigdgmm-dev libpciaccess-dev bzip2; \
    # libvpl2 + libmfx1: oneVPL dispatcher + legacy MediaSDK fallback.
    # Build deps (build-essential, cmake, meson, ninja, dev headers)
    # are temporary — purged after the libva and vpl-gpu-rt builds.
    #
    # === libva 2.22 from source (v0.3.88+) ===
    # BtbN n7.x ffmpeg expects libva ≥ 2.20 (vaMapBuffer2). Ubuntu 22.04
    # stock libva is 2.14, too old. libva 2.x is ABI-stable so iHD and
    # mesa drivers (compiled against 2.14) keep working against 2.22.
    LIBVA_VER=2.22.0; \
    curl -fsSL "https://github.com/intel/libva/releases/download/${LIBVA_VER}/libva-${LIBVA_VER}.tar.bz2" -o /tmp/libva.tar.bz2; \
    mkdir -p /tmp/libva-src; \
    tar xjf /tmp/libva.tar.bz2 -C /tmp/libva-src --strip-components=1; \
    cd /tmp/libva-src; \
    meson setup build --prefix=/usr -Dlibdir=lib/x86_64-linux-gnu --buildtype=release; \
    ninja -C build install; \
    cd /; rm -rf /tmp/libva-src /tmp/libva.tar.bz2; \
    ldconfig; \
    # === vpl-gpu-rt (libmfx-gen) from source (v0.3.89+) ===
    # Intel's modern oneVPL GPU runtime; not packaged for Ubuntu 22.04.
    # Without it, libvpl2 dispatcher falls back to legacy libmfx1 which
    # rejects libva-2.22 displays with MFX_ERR_INCOMPATIBLE_VIDEO_PARAM.
    # ~3 min build on x86_64.
    VPL_VER=24.4.4; \
    curl -fsSL "https://github.com/intel/vpl-gpu-rt/archive/refs/tags/intel-onevpl-${VPL_VER}.tar.gz" -o /tmp/vpl.tar.gz; \
    mkdir -p /tmp/vpl-src; \
    tar xzf /tmp/vpl.tar.gz -C /tmp/vpl-src --strip-components=1; \
    cd /tmp/vpl-src; \
    # Memory-conservative configure (v0.3.92+) — see Dockerfile for the
    # full rationale. Short version: default `--parallel` OOM-kills
    # the GHA free runner during mfx_common_hw linking. Build serially
    # and skip optional optimisation passes that need extra RAM.
    cmake -B build \
        -DCMAKE_BUILD_TYPE=MinSizeRel \
        -DCMAKE_INSTALL_PREFIX=/usr \
        -DCMAKE_INSTALL_LIBDIR=lib/x86_64-linux-gnu \
        -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
        -DBUILD_TESTS=OFF; \
    cmake --build build --parallel 1; \
    cmake --install build; \
    cd /; rm -rf /tmp/vpl-src /tmp/vpl.tar.gz; \
    ldconfig; \
    apt-get purge -y build-essential cmake meson ninja-build pkg-config libdrm-dev libigdgmm-dev libpciaccess-dev bzip2; \
    apt-get autoremove -y; \
    # === Intel media driver 25.2.4 (v0.9.160) ===
    # Ubuntu 24.04's iHD driver (24.1) is too old for Arc / Flex cards (DG2,
    # ATS-M): vaInitialize fails with "iHD_drv_video.so init failed" (GitHub
    # issue, Flex 170). Intel's own build (its Ubuntu 22.04 repo, same files
    # as the standard image) is built for libva 2.22 (the one above) and
    # supports Broadwell through Battlemage. Pinned by version and hash.
    INTEL_POOL=https://repositories.intel.com/gpu/ubuntu/pool/unified/i; \
    curl -fsSL --retry 5 --retry-delay 3 -o /tmp/libigdgmm12.deb "${INTEL_POOL}/intel-gmmlib/libigdgmm12_22.7.2-1135~22.04_amd64.deb"; \
    curl -fsSL --retry 5 --retry-delay 3 -o /tmp/intel-media.deb "${INTEL_POOL}/intel-media-driver-non-free/intel-media-va-driver-non-free_25.2.4-1146~22.04_amd64.deb"; \
    printf '%s  %s\n' \
        c8b3dfbc044735e9502fd4b8e9560f9118afd49755f8caa4d173b0a84044638d /tmp/libigdgmm12.deb \
        fa22334f9431985f2b09748c365e61f54ff7b9b2a01a9c6d1cf24c1075a315fc /tmp/intel-media.deb \
        | sha256sum -c -; \
    apt-get install -y --no-install-recommends /tmp/libigdgmm12.deb /tmp/intel-media.deb; \
    rm -f /tmp/libigdgmm12.deb /tmp/intel-media.deb; \
    rm -rf /var/lib/apt/lists/*

# Install ffmpeg with NVENC + libvmaf.
# BtbN GPL static builds include: NVENC, libvmaf, x265, and all common codecs.
#
# FFMPEG_BUILD picks which BtbN release asset to install. The NVENC SDK baked
# in determines the minimum NVIDIA driver required on the host:
#   n7.1    = NVENC SDK 12.2  → driver 525.60.13+  (DEFAULT — widest compat)
#   n8.1    = NVENC SDK 13.0  → driver 570.00+
#   master  = NVENC SDK 13.0  → driver 570.00+     (bleeding edge)
#
# All are assets of the same rolling `latest` BtbN release, but the filename
# pattern differs: `master` builds have no version suffix, while tagged
# releases (nX.Y) append "-X.Y" to the filename.
# Override at build time:
#   docker build --build-arg FFMPEG_BUILD=master -t shrinkerr:edge .
ARG FFMPEG_BUILD=n8.1
RUN set -e; \
    case "${FFMPEG_BUILD}" in \
        master) FF_URL="https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz" ;; \
        n*)     FF_VER="${FFMPEG_BUILD#n}"; \
                FF_URL="https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-${FFMPEG_BUILD}-latest-linux64-gpl-${FF_VER}.tar.xz" ;; \
        *)      echo "Unknown FFMPEG_BUILD: ${FFMPEG_BUILD} (expected 'master' or 'nX.Y')" >&2; exit 2 ;; \
    esac; \
    echo "Installing ffmpeg build: ${FFMPEG_BUILD} from ${FF_URL}"; \
    # v0.9.105: download to a file with retries, THEN extract (piping curl into
    # tar can't retry a mid-stream cut). See Dockerfile for the full rationale.
    curl -fsSL --retry 5 --retry-delay 3 --retry-all-errors "${FF_URL}" -o /tmp/ffmpeg.tar.xz; \
    tar -xJf /tmp/ffmpeg.tar.xz --strip-components=2 -C /usr/local/bin/ --wildcards '*/bin/ffmpeg' '*/bin/ffprobe'; \
    rm -f /tmp/ffmpeg.tar.xz; \
    chmod +x /usr/local/bin/ffmpeg /usr/local/bin/ffprobe; \
    echo "ffmpeg installed:"; ffmpeg -version 2>&1 | head -1; \
    echo "VMAF filter:"; (ffmpeg -filters 2>&1 | grep libvmaf || echo "NOT FOUND")

# v0.9.8: subtile-ocr for VobSub (DVD, dvd_subtitle) subtitle OCR. pgsrip
# (already installed via pip) handles PGS/Blu-ray only and can't read VobSub,
# so DVD image subs get their own tool. Built from crates.io — but via a
# rustup stable toolchain, NOT Ubuntu 24.04's apt cargo (1.75): subtile-ocr's
# deps use Rust edition 2024, which needs Cargo ≥ 1.85 (v0.9.9). The whole
# toolchain (rustup + build headers) is installed and purged in this ONE layer,
# so it doesn't bloat the image — only /usr/local/bin/subtile-ocr and the
# tesseract/leptonica RUNTIME libs (kept by tesseract-ocr) remain. GUARDED
# with `|| echo` so a build failure NEVER breaks the image — the runtime code
# is fail-open and leaves VobSub tracks `und` when the binary is absent.
RUN set -eux; \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        ca-certificates curl gcc libc6-dev \
        clang libclang-dev libtesseract-dev libleptonica-dev pkg-config; \
    ( export RUSTUP_HOME=/opt/rustup CARGO_HOME=/opt/cargo \
        && curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable \
        && /opt/cargo/bin/cargo install subtile-ocr --root /usr/local \
        && /usr/local/bin/subtile-ocr --version ) \
        || echo "[BUILD] subtile-ocr install failed — VobSub OCR will be unavailable"; \
    apt-get purge -y clang libclang-dev libtesseract-dev libleptonica-dev pkg-config gcc libc6-dev; \
    apt-get autoremove -y; \
    rm -rf /var/lib/apt/lists/* /opt/rustup /opt/cargo

# Record the ffmpeg lineage + its NVENC-SDK driver floor so the backend can
# produce an actionable error message if the runtime NVENC test fails. Read
# by backend/nodes.py during startup-time capability detection.
ENV SHRINKERR_FFMPEG_BUILD=${FFMPEG_BUILD}
ARG NVENC_MIN_DRIVER=525.60.13
ENV SHRINKERR_NVENC_MIN_DRIVER=${NVENC_MIN_DRIVER}

# Use python3.12 as default (Ubuntu 24.04's stock Python, v0.5.13+)
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1

WORKDIR /app

# Install Python dependencies.
# Ubuntu 24.04's system Python carries the PEP 668 "externally-managed"
# marker that blocks pip on the system interpreter unless --break-system-
# packages is passed. This is a single-app container so installing into
# the system Python is the right call; the flag is the standard escape
# hatch for the Docker use case. v0.5.13+.
COPY requirements.txt .
RUN pip3 install --no-cache-dir --break-system-packages -r requirements.txt

# Copy backend and version file
COPY backend/ backend/
COPY VERSION .
# CHANGELOG is read at runtime by /api/stats/changelog so the Updates
# section in Settings can show release notes without a network call.
COPY CHANGELOG.md .

# Copy built frontend
COPY --from=frontend-build /app/frontend/dist frontend/dist

# Create data directory
RUN mkdir -p /app/data

EXPOSE 6680

# Bundled TMDB non-commercial API key — see Dockerfile for notes.
ARG TMDB_API_KEY=""
ENV SHRINKERR_TMDB_API_KEY=${TMDB_API_KEY}

HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
  CMD python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:6680/api/health')" || exit 1

# SHRINKERR_MODE=worker → run as a remote worker node (no server, no UI)
# Default (server) → run the FastAPI server with UI
CMD ["python3", "-m", "backend.main"]