Agent skill

ffmpeg-docker-containers

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/ffmpeg-docker-containers

SKILL.md

CRITICAL GUIDELINES

Windows File Path Requirements

MANDATORY: Always Use Backslashes on Windows for File Paths

When using Edit or Write tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).


Quick Reference

Image Size GPU Command
jrottenberg/ffmpeg:7.1-alpine320 ~100MB No docker run --rm -v $(pwd):/data jrottenberg/ffmpeg:7.1-alpine320 -i /data/input.mp4 /data/output.mp4
jrottenberg/ffmpeg:7.1-nvidia2404 ~1.5GB NVIDIA docker run --gpus all --rm -v $(pwd):/data jrottenberg/ffmpeg:7.1-nvidia2404 ...
jrottenberg/ffmpeg:7.1-vaapi2404 ~300MB Intel/AMD Add --device /dev/dri:/dev/dri
linuxserver/ffmpeg:latest ~150MB No LinuxServer.io maintained

When to Use This Skill

Use for containerized FFmpeg deployments:

  • CI/CD pipelines needing consistent FFmpeg versions
  • Multi-user systems with different FFmpeg requirements
  • Production transcoding services
  • Kubernetes video processing jobs
  • GPU passthrough configurations

FFmpeg in Docker Containers (2025)

Complete guide to running FFmpeg in Docker containers with GPU support, optimization, and production patterns.

Why Docker for FFmpeg?

Benefits

  • Isolation: No dependency conflicts on host system
  • Reproducibility: Same FFmpeg version everywhere
  • Portability: Works identically across platforms
  • Easy updates: Switch FFmpeg versions by changing image tag
  • CI/CD integration: Consistent builds in pipelines
  • GPU access: NVIDIA, Intel, AMD hardware acceleration

When to Use Docker

  • Multi-user environments with different FFmpeg requirements
  • CI/CD pipelines requiring specific FFmpeg builds
  • Production transcoding services
  • Containerized microservices architectures
  • When you need specific codecs/features not in system FFmpeg

Popular FFmpeg Docker Images

jrottenberg/ffmpeg (Recommended)

Most popular and well-maintained FFmpeg Docker image.

Available variants:

Tag Base Size Use Case
7.1-ubuntu2404 Ubuntu 24.04 LTS ~250MB Production, full features
7.1-alpine320 Alpine 3.20 ~100MB Minimal, fast startup
7.1-nvidia2404 Ubuntu + CUDA ~1.5GB NVIDIA GPU
7.1-vaapi2404 Ubuntu + VAAPI ~300MB Intel/AMD GPU (Linux)
7.1-scratch Scratch ~80MB Minimal, static binary
8.0-ubuntu2404 Ubuntu 24.04 LTS ~250MB Latest FFmpeg 8.0
bash
# Pull specific version
docker pull jrottenberg/ffmpeg:7.1-ubuntu2404

# Latest (not recommended for production)
docker pull jrottenberg/ffmpeg:latest

linuxserver/ffmpeg

Designed for ephemeral command-line usage.

bash
docker pull linuxserver/ffmpeg:latest

mwader/static-ffmpeg

Statically compiled FFmpeg binary.

bash
docker pull mwader/static-ffmpeg:7.1

Basic Usage

Simple Transcode

bash
# Mount current directory and run FFmpeg
docker run --rm \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /data/input.mp4 \
  -c:v libx264 \
  -c:a aac \
  /data/output.mp4

Windows (PowerShell)

powershell
# Windows PowerShell
docker run --rm `
  -v ${PWD}:/data `
  jrottenberg/ffmpeg:7.1-ubuntu2404 `
  -i /data/input.mp4 `
  -c:v libx264 `
  /data/output.mp4

Windows (Git Bash/MINGW)

bash
# Git Bash requires MSYS_NO_PATHCONV to prevent path conversion
MSYS_NO_PATHCONV=1 docker run --rm \
  -v "$(pwd)":/data \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /data/input.mp4 \
  -c:v libx264 \
  /data/output.mp4

Using Absolute Paths

bash
# Linux/macOS
docker run --rm \
  -v /home/user/videos:/input:ro \
  -v /home/user/output:/output \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /input/video.mp4 \
  /output/converted.mp4

# Windows
docker run --rm \
  -v C:\Videos:/input:ro \
  -v C:\Output:/output \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /input/video.mp4 \
  /output/converted.mp4

GPU Acceleration in Docker

NVIDIA GPU (Docker + NVIDIA Container Toolkit)

Requirements:

  1. NVIDIA GPU with NVENC support
  2. NVIDIA drivers 450+
  3. NVIDIA Container Toolkit installed

Install NVIDIA Container Toolkit:

bash
# Ubuntu/Debian
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Run with NVIDIA GPU:

bash
docker run --rm --gpus all \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-nvidia2404 \
  -hwaccel cuda \
  -hwaccel_output_format cuda \
  -i /data/input.mp4 \
  -c:v h264_nvenc \
  -preset p4 \
  /data/output.mp4

Select specific GPU:

bash
# Use GPU 0 only
docker run --rm --gpus '"device=0"' \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-nvidia2404 \
  -hwaccel cuda -i /data/input.mp4 -c:v h264_nvenc /data/output.mp4

# Use multiple GPUs
docker run --rm --gpus '"device=0,1"' \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-nvidia2404 \
  ...

Intel QSV/VAAPI (Linux)

bash
# Intel GPU with VAAPI
docker run --rm \
  --device=/dev/dri:/dev/dri \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-vaapi2404 \
  -hwaccel vaapi \
  -hwaccel_device /dev/dri/renderD128 \
  -hwaccel_output_format vaapi \
  -i /data/input.mp4 \
  -vf 'format=nv12|vaapi,hwupload' \
  -c:v h264_vaapi \
  /data/output.mp4

AMD GPU (Linux VAAPI)

bash
docker run --rm \
  --device=/dev/dri:/dev/dri \
  --device=/dev/kfd:/dev/kfd \
  --group-add video \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-vaapi2404 \
  -hwaccel vaapi \
  -hwaccel_device /dev/dri/renderD128 \
  -i /data/input.mp4 \
  -c:v h264_vaapi \
  /data/output.mp4

Building Custom FFmpeg Images

Minimal Custom Dockerfile

dockerfile
FROM ubuntu:24.04 AS builder

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    build-essential \
    pkg-config \
    yasm \
    nasm \
    git \
    wget \
    libx264-dev \
    libx265-dev \
    libvpx-dev \
    libfdk-aac-dev \
    libmp3lame-dev \
    libopus-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /tmp/ffmpeg
RUN wget -O ffmpeg.tar.bz2 https://ffmpeg.org/releases/ffmpeg-7.1.tar.bz2 && \
    tar xjf ffmpeg.tar.bz2 --strip-components=1

RUN ./configure \
    --enable-gpl \
    --enable-nonfree \
    --enable-libx264 \
    --enable-libx265 \
    --enable-libvpx \
    --enable-libfdk-aac \
    --enable-libmp3lame \
    --enable-libopus \
    --disable-doc \
    --disable-debug && \
    make -j$(nproc) && \
    make install

# Production stage
FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    libx264-164 \
    libx265-209 \
    libvpx9 \
    libfdk-aac2 \
    libmp3lame0 \
    libopus0 \
    && rm -rf /var/lib/apt/lists/*

COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin/
COPY --from=builder /usr/local/bin/ffprobe /usr/local/bin/

ENTRYPOINT ["ffmpeg"]

Build with NVIDIA Support

dockerfile
FROM nvidia/cuda:12.4-devel-ubuntu24.04 AS builder

ENV DEBIAN_FRONTEND=noninteractive

# Install build dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    pkg-config \
    yasm \
    nasm \
    git \
    wget \
    libx264-dev \
    libx265-dev \
    && rm -rf /var/lib/apt/lists/*

# Install nv-codec-headers
RUN git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git && \
    cd nv-codec-headers && \
    make install

# Build FFmpeg
WORKDIR /tmp/ffmpeg
RUN wget -O ffmpeg.tar.bz2 https://ffmpeg.org/releases/ffmpeg-7.1.tar.bz2 && \
    tar xjf ffmpeg.tar.bz2 --strip-components=1

RUN ./configure \
    --enable-gpl \
    --enable-nonfree \
    --enable-cuda-nvcc \
    --enable-libnpp \
    --enable-nvenc \
    --enable-nvdec \
    --enable-cuvid \
    --enable-libx264 \
    --enable-libx265 \
    --extra-cflags=-I/usr/local/cuda/include \
    --extra-ldflags=-L/usr/local/cuda/lib64 && \
    make -j$(nproc) && \
    make install

# Production stage
FROM nvidia/cuda:12.4-runtime-ubuntu24.04

RUN apt-get update && apt-get install -y \
    libx264-164 \
    libx265-209 \
    && rm -rf /var/lib/apt/lists/*

COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin/
COPY --from=builder /usr/local/bin/ffprobe /usr/local/bin/

ENTRYPOINT ["ffmpeg"]

Docker Compose Patterns

Simple Transcoding Service

yaml
version: '3.8'

services:
  ffmpeg:
    image: jrottenberg/ffmpeg:7.1-ubuntu2404
    volumes:
      - ./input:/input:ro
      - ./output:/output
    command: >
      -i /input/video.mp4
      -c:v libx264 -crf 23
      -c:a aac -b:a 128k
      /output/converted.mp4

GPU-Accelerated Service

yaml
version: '3.8'

services:
  ffmpeg-gpu:
    image: jrottenberg/ffmpeg:7.1-nvidia2404
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    volumes:
      - ./input:/input:ro
      - ./output:/output
    command: >
      -hwaccel cuda
      -hwaccel_output_format cuda
      -i /input/video.mp4
      -c:v h264_nvenc
      /output/output.mp4

Watch Folder Processing

yaml
version: '3.8'

services:
  ffmpeg-watcher:
    image: jrottenberg/ffmpeg:7.1-ubuntu2404
    volumes:
      - ./watch:/watch
      - ./done:/done
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        while true; do
          for f in /watch/*.mp4; do
            [ -e "$$f" ] || continue
            filename=$$(basename "$$f")
            ffmpeg -i "$$f" -c:v libx264 -crf 23 "/done/$$filename"
            rm "$$f"
          done
          sleep 5
        done
    restart: unless-stopped

Kubernetes Deployment

FFmpeg Job

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: ffmpeg-transcode
spec:
  template:
    spec:
      containers:
        - name: ffmpeg
          image: jrottenberg/ffmpeg:7.1-ubuntu2404
          command:
            - ffmpeg
            - -i
            - /input/video.mp4
            - -c:v
            - libx264
            - /output/output.mp4
          volumeMounts:
            - name: input
              mountPath: /input
              readOnly: true
            - name: output
              mountPath: /output
      volumes:
        - name: input
          persistentVolumeClaim:
            claimName: input-pvc
        - name: output
          persistentVolumeClaim:
            claimName: output-pvc
      restartPolicy: Never

GPU-Enabled Pod (NVIDIA)

yaml
apiVersion: v1
kind: Pod
metadata:
  name: ffmpeg-gpu
spec:
  containers:
    - name: ffmpeg
      image: jrottenberg/ffmpeg:7.1-nvidia2404
      resources:
        limits:
          nvidia.com/gpu: 1
      command:
        - ffmpeg
        - -hwaccel
        - cuda
        - -i
        - /input/video.mp4
        - -c:v
        - h264_nvenc
        - /output/output.mp4
      volumeMounts:
        - name: input
          mountPath: /input
        - name: output
          mountPath: /output
  volumes:
    - name: input
      hostPath:
        path: /data/input
    - name: output
      hostPath:
        path: /data/output

Performance Optimization

Volume Mount Best Practices

bash
# Read-only input for security
docker run --rm \
  -v $(pwd)/input:/input:ro \
  -v $(pwd)/output:/output \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /input/video.mp4 /output/output.mp4

# Use tmpfs for temp files
docker run --rm \
  --tmpfs /tmp:size=1G \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /data/input.mp4 /data/output.mp4

Resource Limits

bash
# Limit CPU and memory
docker run --rm \
  --cpus="4" \
  --memory="4g" \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -threads 4 \
  -i /data/input.mp4 /data/output.mp4

Parallel Processing

bash
# Process multiple files in parallel
for f in *.mp4; do
  docker run --rm -d \
    --cpus="2" \
    -v $(pwd):/data \
    jrottenberg/ffmpeg:7.1-ubuntu2404 \
    -i "/data/$f" "/data/converted_$f"
done

Troubleshooting

Common Issues

Permission denied on output:

bash
# Check file ownership
ls -la output/

# Run with current user
docker run --rm \
  --user $(id -u):$(id -g) \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /data/input.mp4 /data/output.mp4

GPU not detected:

bash
# Verify NVIDIA runtime
docker run --rm --gpus all nvidia/cuda:12.4-base-ubuntu24.04 nvidia-smi

# Check Docker GPU support
docker info | grep -i gpu

Path conversion issues (Git Bash):

bash
# Set MSYS_NO_PATHCONV
MSYS_NO_PATHCONV=1 docker run ...

# Or add to ~/.bashrc
export MSYS_NO_PATHCONV=1

Out of memory:

bash
# Increase memory limit
docker run --rm --memory="8g" --memory-swap="8g" ...

# Use streaming mode
docker run --rm \
  -v $(pwd):/data \
  jrottenberg/ffmpeg:7.1-ubuntu2404 \
  -i /data/input.mp4 \
  -f segment -segment_time 60 \
  /data/output_%03d.mp4

Debug Commands

bash
# Enter container shell
docker run --rm -it \
  --entrypoint /bin/bash \
  jrottenberg/ffmpeg:7.1-ubuntu2404

# Check FFmpeg version and capabilities
docker run --rm jrottenberg/ffmpeg:7.1-ubuntu2404 -version
docker run --rm jrottenberg/ffmpeg:7.1-ubuntu2404 -encoders
docker run --rm jrottenberg/ffmpeg:7.1-ubuntu2404 -hwaccels

Best Practices

  1. Pin image versions - Use specific tags, not latest
  2. Use read-only mounts for input files
  3. Limit resources to prevent host exhaustion
  4. Use multi-stage builds for custom images
  5. Log to stdout/stderr for container logging
  6. Health checks for long-running services
  7. Clean up containers with --rm flag
  8. Security - Run as non-root when possible

This guide covers Docker FFmpeg patterns. For hardware acceleration specifics, see the hardware acceleration skill.

Didn't find tool you were looking for?

Be as detailed as possible for better results