Dockerfile.worker.gpu
Rama dev · réplica de lectura del repositorio original.
# VLog Remote Transcoding Worker with GPU Support (Rocky Linux 10)
# Containerized worker with NVIDIA NVENC and Intel VAAPI hardware encoding
#
# Build: docker build -f Dockerfile.worker.gpu -t vlog-worker-gpu .
# Run (NVIDIA): docker run --gpus all -e VLOG_WORKER_API_KEY=<key> vlog-worker-gpu
# Run (Intel): docker run --device /dev/dri -e VLOG_WORKER_API_KEY=<key> vlog-worker-gpu
# Run (Both): docker run --gpus all --device /dev/dri -e VLOG_WORKER_API_KEY=<key> vlog-worker-gpu
#
# Base: Rocky Linux 10 with RPM Fusion packages
# - FFmpeg 7.1.2 with nvenc, vaapi, qsv encoders (from RPM Fusion)
# - intel-media-driver 25.2.6 for Battlemage/Arc support (from RPM Fusion)
# - NVIDIA libraries injected at runtime via nvidia-container-toolkit
# Pin base image version for reproducible builds
# Update this periodically and test before deploying
ARG ROCKY_VERSION=10
# Code version for worker compatibility checking
# Set this during build: docker build --build-arg CODE_VERSION=$(git rev-parse --short HEAD) ...
ARG CODE_VERSION=dev
ARG BUILD_TIMESTAMP=""
# =============================================================================
# Stage 1: Builder - Install build dependencies and Python packages
# =============================================================================
FROM rockylinux/rockylinux:${ROCKY_VERSION} AS builder
# Install EPEL and RPM Fusion repositories
RUN dnf install -y epel-release && \
dnf install -y --nogpgcheck \
https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-10.noarch.rpm \
https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-10.noarch.rpm && \
dnf clean all
# Install Python 3.12 and build dependencies for packages with C extensions (argon2-cffi)
RUN dnf install -y \
python3.12 \
python3.12-pip \
python3.12-devel \
gcc \
libffi-devel \
&& dnf clean all && \
alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 && \
alternatives --install /usr/bin/pip3 pip3 /usr/bin/pip3.12 1
WORKDIR /build
# Install the same dependency manifest used by the APIs and CI.
COPY pyproject.toml requirements.lock README.md ./
RUN pip3 install --no-cache-dir --prefix=/install --require-hashes -r requirements.lock
# Copy source code and install the package
COPY config.py ./
COPY code_version.py ./
COPY api/ api/
COPY worker/ worker/
COPY cli/ cli/
COPY backup/ backup/
# Create constraints file for security-patched transitive dependencies
RUN echo "filelock>=3.20.3" > /tmp/constraints.txt && \
echo "jaraco-context>=6.1.0" >> /tmp/constraints.txt && \
pip3 install --no-cache-dir --no-deps --prefix=/install -c /tmp/constraints.txt .
# =============================================================================
# Stage 2: Runtime - Minimal production image
# =============================================================================
FROM rockylinux/rockylinux:${ROCKY_VERSION} AS runtime
# Install EPEL and RPM Fusion repositories
RUN dnf install -y epel-release && \
dnf install -y --nogpgcheck \
https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-10.noarch.rpm \
https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-10.noarch.rpm && \
dnf clean all
# Install FFmpeg with hardware acceleration support and curl for health checks
# RPM Fusion's FFmpeg 7.1.2 includes nvenc, vaapi, and qsv encoders
RUN dnf install -y \
ffmpeg \
ffmpeg-libs \
curl \
&& dnf clean all
# Install Intel VAAPI driver for Arc/Battlemage support
# intel-media-driver 25.2.6 from RPM Fusion supports Battlemage (Arc B580)
# Note: libva and mesa-dri-drivers are pulled in as ffmpeg dependencies
RUN dnf install -y \
intel-media-driver \
&& dnf clean all
# Install Python 3.12 runtime (no devel packages needed)
RUN dnf install -y \
python3.12 \
python3.12-pip \
&& dnf clean all && \
alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 && \
alternatives --install /usr/bin/pip3 pip3 /usr/bin/pip3.12 1
# Patch OS packages AFTER every dnf install above.
# This must stay last: intel-media-driver and python3.12 pull in transitive
# packages (giflib, gnutls, libsoup3, mesa-*) that an earlier `dnf update`
# cannot possibly have covered, which left known CVEs in the shipped image.
RUN dnf update -y && dnf clean all && rm -rf /var/cache/dnf
# Create non-root user for security
RUN useradd -m -u 1000 -s /bin/bash vlog && \
usermod -aG video vlog
WORKDIR /app
# Copy installed Python packages from builder
COPY --from=builder /install /usr/local
# Copy source code
COPY --chown=vlog:vlog config.py ./
COPY --chown=vlog:vlog code_version.py ./
COPY --chown=vlog:vlog api/ api/
COPY --chown=vlog:vlog worker/ worker/
COPY --chown=vlog:vlog cli/ cli/
COPY --chown=vlog:vlog backup/ backup/
COPY --chown=vlog:vlog pyproject.toml ./
# Re-declare build args for use in this stage (args don't persist across stages)
ARG CODE_VERSION=dev
ARG BUILD_TIMESTAMP=""
# Switch to non-root user
USER vlog
# Create work directory
RUN mkdir -p /tmp/vlog-worker
# Environment variables
# VLOG_CODE_VERSION and VLOG_BUILD_TIMESTAMP are used for worker compatibility checking
ENV VLOG_WORKER_API_URL=http://vlog-worker-api:9002 \
VLOG_WORKER_WORK_DIR=/tmp/vlog-worker \
VLOG_WORKER_HEARTBEAT_INTERVAL=30 \
VLOG_WORKER_POLL_INTERVAL=10 \
# Code version for compatibility checking
VLOG_CODE_VERSION=${CODE_VERSION} \
VLOG_BUILD_TIMESTAMP=${BUILD_TIMESTAMP} \
# GPU detection (auto-detect by default)
VLOG_HWACCEL_TYPE=auto \
VLOG_HWACCEL_PREFERRED_CODEC=av1 \
# NVIDIA runtime (nvidia-container-toolkit injects libraries)
NVIDIA_VISIBLE_DEVICES=all \
NVIDIA_DRIVER_CAPABILITIES=compute,video,utility \
# Intel VAAPI - use renderD128 by default (can be overridden)
LIBVA_DRIVER_NAME=iHD \
# Python settings
PYTHONUNBUFFERED=1
# Health check - verify worker's health server is responding
# The worker exposes /health on port 8080 which verifies:
# - Worker process is alive
# - API connection is working
# - FFmpeg is available (including GPU codecs)
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Run the remote transcoder
CMD ["python3", "-m", "worker.remote_transcoder"]