Smart Transcode

Troubleshooting: Docker

For the aarondyck/smart-transcode image run with Docker. The examples use the container name smart-transcode from the compose files; change it if yours differs.

First: look at the container

docker ps -a --filter name=smart-transcode          # running? restarting? "unhealthy"?
docker logs --tail 100 smart-transcode               # the first line names the user: "… as transcode (1000:1000, groups: …)"
docker exec smart-transcode id transcode             # the uid / gid and groups it runs as
docker exec smart-transcode tail -n 50 /config/transcode.log     # the application log (it is also in your config folder)

A container that keeps restarting has a start-up error: docker logs shows it (a bad PUID/PGID value, a config folder it cannot write, a missing mount).

I cannot open the page

  • Is the port published? docker port smart-transcode should show 8080/tcp -> 0.0.0.0:8080. The container always listens on 8080; the left number in ports: is the host port.
  • Port already in use on the host: change the left number ("8090:8080") and docker compose up -d.
  • Test from the host: curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/api/auth/me should print 200. If yes, the firewall is blocking other machines (sudo firewall-cmd --add-port=8080/tcp --permanent && sudo firewall-cmd --reload on firewalld).
  • “unhealthy”: the health check calls the page from inside; docker logs shows why it does not answer (still starting, a crash loop, the database is locked or unreadable).
  • Behind a reverse proxy: forward to the container's port 8080, pass the Host header unchanged and list the proxy in Settings → Security → Reverse proxies. Reverse proxy.

Permission denied, empty library, wrong file owner

Almost always PUID / PGID (see User and group IDs). Compare the numbers the host and the container see:

ls -ln /srv/media                                    # on the host: the owner numbers
docker exec smart-transcode ls -ln /srv/media        # inside: must show the same numbers
docker exec smart-transcode id transcode             # PUID / PGID the app runs as
docker exec -u transcode smart-transcode touch /srv/media/.write-test && echo writable
  • Not the same owner or group: set PUID / PGID to the owner of your media (stat -c '%u:%g' /srv/media) and recreate: docker compose up -d.
  • Folder missing inside: the path you add in Settings is the path inside the container (the right side of the volume mapping).
  • “unable to open database file”: the /config folder is not writable by the app's user. With PUID/PGID the container fixes ownership itself; with user: set you must chown it yourself. Keep it on a local disk, not a network share.
  • Network shares (NFS / SMB): the numbers come from the server or your mount options: see the ID guide.
  • SELinux hosts (Fedora, RHEL, Rocky): a volume may need :z (- /srv/media:/srv/media:z) or security_opt: ["label=disable"]. Check with sudo ausearch -m avc -ts recent.

My GPU is not listed (or conversions use the CPU)

NVIDIA

nvidia-smi                                                  # on the host: driver works?
docker run --rm --gpus all ubuntu nvidia-smi                # the NVIDIA Container Toolkit works?
docker exec smart-transcode nvidia-smi                      # the container sees the GPU?
docker exec smart-transcode ffmpeg -hide_banner -encoders | grep nvenc
  • The compose file needs the deploy.resources.reservations.devices block (driver nvidia) and NVIDIA_DRIVER_CAPABILITIES: compute,video,utility; without video there is no NVENC.
  • docker run --gpus all … fails with “could not select device driver”: install the NVIDIA Container Toolkit and run sudo nvidia-ctk runtime configure --runtime=docker && sudo systemctl restart docker.
  • After a host driver update, restart the container; if it still fails, reboot the host (the driver and the userspace libraries must match).

Intel and AMD

ls -l /dev/dri                                      # on the host: renderD128 exists?
docker exec smart-transcode ls -l /dev/dri           # and in the container?
docker exec smart-transcode id transcode             # is the user in the device's group (render / video)?
  • The compose file must pass /dev/dri under devices:. The container joins the device's group itself (the start-up log line lists the groups).
  • With several GPUs, set SMART_TRANSCODE_VAAPI_DEVICE to the right node (ls -l /dev/dri/by-path).
  • If you start the container with user:, group membership is not added: use group_add with the numeric group id of the render node (stat -c %g /dev/dri/renderD128).
  • AMD's AMF encoder does not exist in containers on Linux: pick the AMD VAAPI profile.

Press Re-detect in Settings → Video after any change.

Containers cannot reach the internet or each other

  • Sonarr / Radarr cannot be reached: use a shared Docker network and the container name in the address (http://sonarr:8989), not localhost. They must reach this app the same way for webhooks.
  • The bridge network has no outbound access (pulls or builds time out, DNS fails) on firewalld hosts: allow the Docker bridge, for example sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0 && sudo firewall-cmd --reload && sudo systemctl restart docker.

Conversions fail

  • Open the file's status in History for ffmpeg's messages and the command used. Reproduce it inside: docker exec -u transcode -it smart-transcode bash, paste the command.
  • Disk space: the new file is written next to the original, so a file needs about its size free: docker exec smart-transcode df -h /srv/media.
  • Raise logging to DEBUG in Settings → Debug, reproduce, and read /config/transcode.log.

Updating and starting over

docker compose pull && docker compose up -d       # newer image, same data
docker compose logs -f                              # watch it start
docker compose down                                 # stop and remove the container (data is in ./config)

To go back to a version, set the image tag (aarondyck/smart-transcode:1.0) instead of latest. The database lives in your config folder: copy it before major changes.