Smart Transcode

Run it in Podman

The same image works with Podman 4.4 or newer. The difference that matters is who the container runs as, and so which IDs apply.

Read this first

Whether the container can write your media depends on user and group IDs. Read User and group IDs before you start; it takes five minutes and saves an evening.

Rootless or rootful?

Rootless (normal user)Rootful (sudo podman)
Who is "root" in the containerYou. Container UID 0 is mapped to your host UID; other IDs are mapped into your subuid range and look like a stranger on the host.Real root, as in Docker.
How to get the right file ownerRun as yourself: --userns=keep-id --user $(id -u):$(id -g). PUID / PGID are not used. This is why your media must belong to the user who runs the container.Use PUID / PGID exactly as in Docker.
Mapping cautionWithout keep-id a PUID of 1000 lands on host UID 100999 (or similar) and cannot write your files.None.

Two more Podman details: on Fedora, RHEL and derivatives SELinux blocks containers from your media, so the examples use --security-opt label=disable (the alternative is a :z suffix on each volume, which relabels the whole folder). And images need a full name: docker.io/aarondyck/smart-transcode.

Optional: a helper that writes the files

You do not need this to run the image. The helper is a script in the Linux package (download it and unpack it only if you want it). It writes a compose file and a start script for your hardware and user.

./docker-setup.sh --engine podman --media /srv/media --gpu intel       # nvidia | intel | amd | cpu
cd smart-transcode-docker
./start.sh                      # or: podman compose up -d   (needs podman-compose or docker-compose)

Run it yourself, by GPU

One command per kind of hardware. Rootless examples run as you; the rootful variant is noted under each.

NVIDIA

Host: the NVIDIA driver and the NVIDIA Container Toolkit, then generate the CDI description of your GPUs once (and again after a driver update):

sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
nvidia-ctk cdi list                                          # should list nvidia.com/gpu=all
podman run --rm --device nvidia.com/gpu=all --security-opt label=disable ubuntu nvidia-smi
# rootless: run as yourself (your media must belong to you)
mkdir -p ~/smart-transcode/config
podman run -d --name smart-transcode --restart unless-stopped \
  -p 8080:8080 -e TZ=Europe/London \
  --userns=keep-id --user "$(id -u):$(id -g)" \
  --device nvidia.com/gpu=all --security-opt label=disable \
  -e NVIDIA_DRIVER_CAPABILITIES=compute,video,utility \
  -v ~/smart-transcode/config:/config \
  -v /srv/media:/srv/media \
  docker.io/aarondyck/smart-transcode:latest

Rootful: use sudo podman run, drop --userns and --user, and add -e PUID=1000 -e PGID=1000 -e UMASK=002.

Intel and AMD

The GPU is a device file, so Intel and AMD are the same. --group-add keep-groups carries your own render / video group into the container (your user must be in it: id).

mkdir -p ~/smart-transcode/config
podman run -d --name smart-transcode --restart unless-stopped \
  -p 8080:8080 -e TZ=Europe/London \
  --userns=keep-id --user "$(id -u):$(id -g)" \
  --device /dev/dri --group-add keep-groups --security-opt label=disable \
  -e SMART_TRANSCODE_VAAPI_DEVICE=/dev/dri/renderD128 \
  -v ~/smart-transcode/config:/config \
  -v /srv/media:/srv/media \
  docker.io/aarondyck/smart-transcode:latest

Rootful: sudo podman run … without --userns, --user and --group-add, with -e PUID=1000 -e PGID=1000 -e UMASK=002; the container joins the device's group on its own.

No GPU (CPU only)

mkdir -p ~/smart-transcode/config
podman run -d --name smart-transcode --restart unless-stopped \
  -p 8080:8080 -e TZ=Europe/London \
  --userns=keep-id --user "$(id -u):$(id -g)" --security-opt label=disable \
  -v ~/smart-transcode/config:/config \
  -v /srv/media:/srv/media \
  docker.io/aarondyck/smart-transcode:latest

Start at boot (Quadlet)

Podman runs containers as systemd services through Quadlet. Save this as ~/.config/containers/systemd/smart-transcode.container (rootless; use /etc/containers/systemd/ for rootful), adjust the IDs and paths, then:

[Unit]
Description=Smart Transcode

[Container]
Image=docker.io/aarondyck/smart-transcode:latest
ContainerName=smart-transcode
PublishPort=8080:8080
UserNS=keep-id
User=1000
Group=1000
AddDevice=/dev/dri
GroupAdd=keep-groups
SecurityLabelDisable=true
Volume=%h/smart-transcode/config:/config
Volume=/srv/media:/srv/media

[Service]
Restart=always

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user start smart-transcode
loginctl enable-linger $USER      # keep it running when you are logged out

For NVIDIA replace AddDevice=/dev/dri and GroupAdd with AddDevice=nvidia.com/gpu=all. Update the image with podman pull docker.io/aarondyck/smart-transcode:latest and restart the service.