Files
homelab-configs/jellyfin/jellyfin-services.md
T

2.8 KiB

Jellyfin Server — Docker Services

Host

  • VM / alias: jellyfin
  • IP: 192.168.88.10
  • SSH: jgitta@192.168.88.10 (alias: jellyfin)
  • Portainer endpoint ID: 4
  • Compose files: managed via Portainer (stack IDs below); source of truth is Gitea jgitta/homelab-configs

Stacks

Stack Portainer ID Gitea Path
arr-stack 35 jellyfin/arr-stack/docker-compose.yml
portainer-agent 36 jellyfin/portainer-agent/
node-exporter 44 jellyfin/node-exporter/

arr-stack Services

Container Image Port Config Path
radarr lscr.io/linuxserver/radarr:latest 7878 /srv/docker/radarr/config
sonarr lscr.io/linuxserver/sonarr:latest 8989 /srv/docker/sonarr/config
prowlarr lscr.io/linuxserver/prowlarr:latest 9696 /srv/docker/prowlarr/config
flaresolverr ghcr.io/flaresolverr/flaresolverr:latest 8191
watchtower containrrr/watchtower see below

Media volume: /mnt/media on jellyfin host → mounted as /data in radarr/sonarr.


Watchtower

  • Runs inside arr-stack on jellyfin (Portainer stack 35)
  • Schedule: 0 0 4 * * * — runs at 4:00 AM daily
  • Notifications: email via Fastmail SMTP to jgitta@jgitta.com
  • Cleanup: enabled (removes old images after update)
  • Rolling restarts: enabled with 30s timeout, 60s wait before stopping

lscr.io Authentication (fix applied 2026-05-11)

Problem: Watchtower was hitting lscr.io's rate limiter on unauthenticated pulls. radarr, sonarr, and prowlarr all use lscr.io/linuxserver/ images; when Watchtower checks them concurrently at 4 AM the burst briefly exceeded the anonymous quota. Error appeared in email notifications as:

Unable to update container "/radarr": Error response from daemon: toomanyrequests:
retry-after: 835.12µs, allowed: 44000/minute. Proceeding to next.

Observed on: 2026-05-08 and 2026-05-11.

Fix:

  1. Logged in to lscr.io on the jellyfin host using the GitHub PAT (credentials.md):

    echo <github_pat> | docker login lscr.io -u jgitta --password-stdin
    

    Creates /home/jgitta/.docker/config.json with lscr.io auth token.

  2. Mounted that config into the Watchtower container (in docker-compose.yml):

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/jgitta/.docker/config.json:/config.json:ro
    

    Watchtower reads /config.json inside the container for registry credentials.

  3. Updated Gitea (jellyfin/arr-stack/docker-compose.yml) and redeployed via Portainer.

If GitHub PAT expires: Re-run the docker login lscr.io command on jellyfin with the new token. No compose changes needed — the mounted file updates automatically. The PAT expiry date is tracked in credentials.md / github.com/settings/tokens.