Jellyfin
Deploy Jellyfin media server.
Ansible hosts group: jellyfin
Variables
| Option | Type | Description | Default |
|---|---|---|---|
cs_jellyfin_ansible_arch_map | dict | Architecture mapping dictionary | {"aarch64": "arm64", "x86_64": "amd64"} |
cs_jellyfin_docker_tag | string | Jellyfin docker tag | 12.2 |
cs_jellyfin_container_image | string | Jellyfin container image | {{ cs_vm_artifact_registry_containers_home }}/jellyfin |
cs_jellyfin_container_name | string | Jellyfin container name | jellyfin |
cs_jellyfin_container_dri_list | list | GPU DRI device list | [] |
cs_jellyfin_user | string | Dedicated user for Jellyfin (no home, no login) | jellyfin |
cs_jellyfin_group | string | Dedicated group for Jellyfin | jellyfin |
cs_jellyfin_user_gid | int | GID for the Jellyfin group | 1982 |
cs_jellyfin_user_uid | int | UID for the Jellyfin user | 1983 |
cs_jellyfin_dns_servers | list | DNS servers for Jellyfin | The cluster's DNS servers (from Vault) |
cs_jellyfin_media_dir | string | Media directory | /app/jellyfin-media |
cs_jellyfin_container_root | string | Container root directory | /app/jellyfin-container-root |
cs_jellyfin_data_dir | string | Data directory | /var/lib/jellyfin |
cs_jellyfin_config_dir | string | Config directory | /etc/jellyfin |
cs_jellyfin_log_dir | string | Log directory | /var/log/jellyfin |
cs_jellyfin_cache_dir | string | Cache directory | /var/cache/jellyfin |
cs_jellyfin_container_media_mounts | list | List of media mounts | [] |
cs_jellyfin_cluster | string | Cluster name | {{ cs_cluster_name }} |
cs_jellyfin_local_subnets | list | Local subnets | The cluster CIDR and VPN CIDR (from Vault) |
cs_jellyfin_known_proxies | list | Known proxies | The cluster CIDR and VPN CIDR (from Vault) |
cs_jellyfin_restic_cluster_name | string | Restic cluster name | {{ cs_jellyfin_cluster }} |
cs_jellyfin_restic_node_name | string | Restic backup node name | {{ inventory_hostname }} |
cs_jellyfin_restic_repo_name | string | Restic repository name | jellyfin |
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-smion the host and, when that succeeds (driver installed and loaded, see thepatch_nvidiastage), starts the container with the NVIDIA runtime and all GPUs (device_requests), plusNVIDIA_VISIBLE_DEVICES=allandNVIDIA_DRIVER_CAPABILITIES=compute,video,utilityfor 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_dirand anycs_jellyfin_container_media_mountsentries 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 deletescs_jellyfin_container_root. Never included by the plainjellyfintag.
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