Skip to main content

Jellyfin

Deploy Jellyfin media server.

Ansible hosts group: jellyfin​

Variables​

OptionTypeDescriptionDefault
cs_jellyfin_ansible_arch_mapdictArchitecture mapping dictionary{"aarch64": "arm64", "x86_64": "amd64"}
cs_jellyfin_docker_tagstringJellyfin docker tag12.2
cs_jellyfin_container_imagestringJellyfin container image{{ cs_vm_artifact_registry_containers_home }}/jellyfin
cs_jellyfin_container_namestringJellyfin container namejellyfin
cs_jellyfin_container_dri_listlistGPU DRI device list[]
cs_jellyfin_userstringDedicated user for Jellyfin (no home, no login)jellyfin
cs_jellyfin_groupstringDedicated group for Jellyfinjellyfin
cs_jellyfin_user_gidintGID for the Jellyfin group1982
cs_jellyfin_user_uidintUID for the Jellyfin user1983
cs_jellyfin_dns_serverslistDNS servers for JellyfinThe cluster's DNS servers (from Vault)
cs_jellyfin_media_dirstringMedia directory/app/jellyfin-media
cs_jellyfin_container_rootstringContainer root directory/app/jellyfin-container-root
cs_jellyfin_data_dirstringData directory/var/lib/jellyfin
cs_jellyfin_config_dirstringConfig directory/etc/jellyfin
cs_jellyfin_log_dirstringLog directory/var/log/jellyfin
cs_jellyfin_cache_dirstringCache directory/var/cache/jellyfin
cs_jellyfin_container_media_mountslistList of media mounts[]
cs_jellyfin_clusterstringCluster name{{ cs_cluster_name }}
cs_jellyfin_local_subnetslistLocal subnetsThe cluster CIDR and VPN CIDR (from Vault)
cs_jellyfin_known_proxieslistKnown proxiesThe cluster CIDR and VPN CIDR (from Vault)
cs_jellyfin_restic_cluster_namestringRestic cluster name{{ cs_jellyfin_cluster }}
cs_jellyfin_restic_node_namestringRestic backup node name{{ inventory_hostname }}
cs_jellyfin_restic_repo_namestringRestic repository namejellyfin

First deployment​

Jellyfin creates network.xml under cs_jellyfin_container_root only after its first-run setup. On a host without that file the play starts the container, then stops with an error that points at the initial setup page (http://<host IP>:<internal HTTP port>/web/index.html). Complete the setup there, then run the play again. Once network.xml exists the play configures its ports, HTTPS certificate, local networks, and known proxies.

Hardware acceleration​

  • Intel/AMD VAAPI is exposed through cs_jellyfin_container_dri_list (DRI devices).
  • The play attaches NVIDIA GPUs automatically: it runs nvidia-smi on the host and, when that succeeds (driver installed and loaded, see the patch_nvidia stage), starts the container with the NVIDIA runtime and all GPUs (device_requests), plus NVIDIA_VISIBLE_DEVICES=all and NVIDIA_DRIVER_CAPABILITIES=compute,video,utility for NVENC/NVDEC. Hosts without a working NVIDIA driver skip these options, and Jellyfin runs unchanged.

Vault configurations​

  • key: {{ cs_project_code }}/application-deployer/clusters/{{ cs_jellyfin_cluster }}/hosts/{{ inventory_hostname }}/apps/jellyfin/config
{
"pkcs12_base64": "(Optional) Base64 encoded PKCS#12 certificate",
"pkcs12_password": "(Optional) PKCS#12 certificate password",
"internal_https_port": "Internal HTTPS port",
"public_http_port": "Public HTTP port",
"public_https_port": "Public HTTPS port",
"internal_http_port": "Internal HTTP port"
}

Backup​

Restic backs up only cs_jellyfin_container_root (Jellyfin's own database/config/cache). cs_jellyfin_media_dir and any cs_jellyfin_container_media_mounts entries sit outside that root and are excluded on purpose: they hold the operator's existing media library, which is stored on and protected by the underlying disks/NAS independently of this repo, not data Jellyfin itself generates.

The {{ cs_jellyfin_container_name }} container is stopped for the duration of the backup and started again afterwards, even if the backup itself fails.

Cleanup (dangerously_cleanup_jellyfin)​

Destructive. Only runs when this exact tag is passed explicitly (it is intentionally excluded from the plain jellyfin tag) and permanently deletes Jellyfin's own data on the host:

  • Removes the {{ cs_jellyfin_container_name }} Docker container.
  • Deletes the UFW allow rules opened for the internal HTTP/HTTPS and public HTTP/HTTPS ports.
  • Deletes cs_jellyfin_container_root. cs_jellyfin_media_dir and any cs_jellyfin_container_media_mounts entries are left untouched, since they hold the operator's existing media library, not data Jellyfin itself generates.
  • Deletes the {{ cs_jellyfin_user }} user, its home directory, and the {{ cs_jellyfin_group }} group.

Tags​

  • jellyfin: Deploy Jellyfin media server.
  • jellyfin_install: Install Jellyfin.
  • jellyfin_restic_backup: Run Restic backup for Jellyfin.
  • jellyfin_restic_restore: Restore Jellyfin's data from the latest Restic snapshot.
  • dangerously_cleanup_jellyfin: Destructive. Removes the Jellyfin Docker container, closes its UFW ports, and deletes cs_jellyfin_container_root. Never included by the plain jellyfin tag.

Deployment​

uv sync --all-extras --all-packages --no-progress
uv --offline run --no-sync --no-progress ansible-galaxy install -r requirements.yml
uv --offline run --no-sync --no-progress ansible-playbook playbook.yml --tags jellyfin