diff --git a/host_config/nomad.hcl b/host_config/nomad.hcl index c6ce3f9..afd9116 100644 --- a/host_config/nomad.hcl +++ b/host_config/nomad.hcl @@ -30,7 +30,7 @@ client { path = "/hdd/gitea/" read_only = false } - + host_volume "minio-ssd" { path = "/ssd/minio/" read_only = false @@ -50,9 +50,24 @@ client { path = "/ssd/sqlite/" read_only = false } + + host_volume "jellyfinCache" { + path = "/hdd/multimedia/cache/" + read_only = false + } + + host_volume "jellyfinConfig" { + path = "/hdd/multimedia/config/" + read_only = false + } + + host_volume "media" { + path = "/hdd/multimedia/media/" + read_only = false + } } ui { # Comment to disable UI, it listens on port 4646 enabled = true -} \ No newline at end of file +} diff --git a/nomad_jobs/services/jellyfin/jellyfin.nomad.hcl b/nomad_jobs/services/jellyfin/jellyfin.nomad.hcl new file mode 100644 index 0000000..4985ef4 --- /dev/null +++ b/nomad_jobs/services/jellyfin/jellyfin.nomad.hcl @@ -0,0 +1,83 @@ +locals { + SUBDOMAIN = "jellyfin." // End with dot or leave blamk for root domain + DOMAIN = "example.com" + TRAEFIK_DOMAIN = "${local.SUBDOMAIN}${local.DOMAIN}" +} + +job "jellfyin" { + datacenters = ["dc1"] + type = "service" + + group "application" { + count = 1 + + network { + mode = "host" + port "httpIngress" { static = 8096 } + port "serviceDiscovery" { static = 1900 } + port "clientDiscovery" { static = 7359 } + } + + volume "jellyfin-cache" { + type = "host" + source = "jellyfinCache" + } + + volume "jellyfin-config" { + type = "host" + source = "jellyfinConfig" + } + + volume "jellyfin-data" { + type = "host" + source = "media" + } + + service { + name = "jellyfin" + port = "httpIngress" + + tags = [ + "traefik.enable=true", + "traefik.http.routers.jellyfin.tls=true", + "traefik.http.routers.jellyfin.entrypoints=websecure", + "traefik.http.routers.jellyfin.rule=Host(`${local.TRAEFIK_DOMAIN}`)" + ] + + check { + type = "http" + path = "/health" + interval = "10s" + timeout = "2s" + } + } + + task "jellyfin" { + driver = "docker" + + config { + image = "jellyfin/jellyfin:2024030405" + ports = ["httpIngress", "serviceDiscovery", "clientDiscovery"] + } + + env = { + JELLYFIN_PublishedServerUrl="${local.TRAEFIK_DOMAIN}" + } + + volume_mount { + volume = "jellyfin-cache" + destination = "/cache" + } + + volume_mount { + volume = "jellyfin-config" + destination = "/config" + } + + volume_mount { + volume = "jellyfin-data" + destination = "/media" + } + } + } +} diff --git a/nomad_jobs/services/jellyfin/readme.md b/nomad_jobs/services/jellyfin/readme.md new file mode 100644 index 0000000..498e193 --- /dev/null +++ b/nomad_jobs/services/jellyfin/readme.md @@ -0,0 +1,36 @@ +# Jellyfin + +Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. + +## Nomad Job for Gitea + +You will need to modify the job spec items listed under [TODO](./readme.md#TODO) but there are no Jellyfin specific adjustments needed. If you run it, it will register with consul and be available to Traefik for routing. If the domain name is configured correctly, you should be able to reach the Jellyfin setup page to make the needed configuration changes such as defining the media libraries. + +## Service Dependencies + +- A Valid [Host Volume](../../../host_init/README.md#storage-and-zfs) For Cache +- A Valid [Host Volume](../../../host_init/README.md#storage-and-zfs) For Config +- A Valid [Host Volume](../../../host_init/README.md#storage-and-zfs) For Media + +## TODO + +If you want to deploy this, you will need to verify you have the necessary host volumes. + +| Line | Default | Adjustment | +| ---- | --------------------------- | --------------------------------------------------------------------------- | +| 23 | `source = "jellyfinCache"` | Change `jellyfinCache` to a valid host volume name | +| 28 | `source = "jellyfinConfig"` | Change `jellyfinConfig` to a valid host volume name | +| 33 | `source = "media"` | Change `media` to a valid host volume name | +| 68 | `volume = "jellyfinCache"` | Change `jellyfinCache` to the host volume defined on line 21 if applicable | +| 74 | `volume = "jellyfinConfig"` | Change `jellyfinConfig` to the host volume defined on line 26 if applicable | +| 79 | `volume = "media"` | Change `media` to the host volume defined on line 31 if applicable | + +> To make the instance accessible through TRAEFIK you will need to define the domain to listen on by setting the value(s) on lines 2 and 3. + +## Configuring Jellyfin + +There is no need to embed secrets in the nomad job spec. When you first visit the domain name you configured, you will be prompted to configure Jellyfin. + +> I recomend using a single root directory for media and then creating subdirectories for each type of media. This will make it easier to manage the media via SFTP and to configure Jellyfin. + +> If this is deployed on Alpine Linux, you won't be able to pass through dedicated NVIDIA hardware because `nvidia-container-toolkit` is not available on MUSL. You will need to use a different root operating system like Ubuntu if you want hardware acceleration with NVIDIA hardware.