Jellyfin¶
Free and Open Source Media Server
Jellyfin is a free, open source media server that puts you in control of your media. It streams movies, TV shows, music, and photos to virtually any device, with no subscriptions or tracking.
Why Choose Jellyfin?¶
- Completely free - no premium tier, no tracking, fully open source
- Multi-device - web, mobile, TV apps, and Chromecast support
- Hardware transcoding - CPU and GPU accelerated transcoding
- Rich metadata - automatic fetching of posters, summaries, and subtitles
Install¶
Infrastructure as Code
This Jellyfin instance is deployed using OpenTofu with a custom Incus image. The infrastructure configuration manages container provisioning, persistent storage, and media library access.
Custom Jellyfin Image
The Jellyfin Incus image is built and maintained at forgejo.benoit.jp.net/Benoit/Laminar.
Infrastructure Configuration¶
The OpenTofu configuration provisions:
- Incus instance running the custom Jellyfin image with 6 CPU cores
- Persistent storage volume for
/var/lib/jellyfin(application data, metadata, database) - Proxy device exposing port 8096 on the host network interface
- Read-only media share mounting TrueNAS downloads at
/mnt/truenas/downloads
resource "incus_storage_volume" "jellyfin_var_lib_jellyfin" {
name = "jellyfin_var_lib_jellyfin"
pool = incus_storage_pool.default.name
config = {
"initial.gid" = "104"
"initial.uid" = "103"
"initial.mode" = "755"
}
}
resource "incus_instance" "jellyfin" {
name = "jellyfin"
image = "laminar.incus:jellyfin-10.10.6-1benoitjpnet"
config = {
"limits.cpu" = 6
}
device {
name = "jellyfin_var_lib_jellyfin"
type = "disk"
properties = {
path = "/var/lib/jellyfin"
source = incus_storage_volume.jellyfin_var_lib_jellyfin.name
pool = incus_storage_pool.default.name
}
}
device {
name = "http"
type = "proxy"
properties = {
listen = "tcp:192.168.1.2:8096"
connect = "tcp:127.0.0.1:8096"
}
}
device {
name = "mnt_truenas_downloads"
type = "disk"
properties = {
path = "/mnt/truenas/downloads"
source = "/mnt/truenas/downloads"
}
}
}
Deploy Infrastructure¶
After provisioning, Jellyfin is accessible at http://192.168.1.2:8096. Complete the initial setup wizard to configure your media libraries, pointing them at /mnt/truenas/downloads.
Upgrade¶
Stateless Upgrade
Because all application data lives on the persistent /var/lib/jellyfin storage volume, upgrading is a simple image version bump, with no backup or restore steps required.
Update the image version in OpenTofu
Edit your OpenTofu configuration to reference the new image version:
resource "incus_instance" "jellyfin" {
name = "jellyfin"
image = "laminar.incus:jellyfin-NEW-VERSION" # (1)!
# ...
}
- Replace
NEW-VERSIONwith the target Jellyfin version tag.
Upgrade Complete
The new container starts with the existing /var/lib/jellyfin volume attached, preserving all metadata, libraries, and user settings.