{ config, lib, pkgs, ... }: let cfg = config.homelab.apps.jellyfin; networkName = "jellyfin"; inherit (config.homelab.fileSystems) media; UID = 3008; GID = config.users.groups.media.gid; in { options.homelab.apps.jellyfin.enable = lib.mkEnableOption "Jellyfin using Docker"; config = lib.mkIf cfg.enable { homelab = { fileSystems.media.video = { enable = true; permissions = [ "read" ]; }; users = { apps.enable = true; media.enable = true; }; virtualisation.containers.enable = true; }; homelab.nfsMounts = let mkMount = device: { inherit device; readOnly = true; }; in { "/srv/audio" = mkMount "192.168.0.11:/mnt/SMALL/MEDIA/AUDIO"; "/srv/homevideo" = mkMount "192.168.0.11:/mnt/BIG/MEDIA/HOMEVIDEO/ARCHIVE"; "/srv/photo" = mkMount "192.168.0.11:/mnt/BIG/MEDIA/PHOTO/ARCHIVE"; }; homelab.appUsers.jellyfin = { uid = UID; extraGroups = [ config.users.groups.media.name ]; }; # Make sure the Docker network exists. homelab.dockerNetworks."${networkName}" = { requiredBy = [ "docker-jellyfin.service" "docker-feishin.service" ]; }; virtualisation.oci-containers.containers = { jellyfin = { hostname = "jellyfin"; image = "jellyfin/jellyfin:10.10.7"; user = "${toString UID}:${toString GID}"; autoStart = true; ports = [ "8096:8096/tcp" # "8920:8920/tcp" ]; extraOptions = [ "--network=${networkName}" "--device=nvidia.com/gpu=all" # Equivalent to --gpus=all ]; volumes = [ "jellyfin-config:/config" "cache:/cache" "/srv/audio:/media/audio" "${media.video.hostPath}:/media/video" "/srv/homevideo:/media/homevideo" "/srv/photo:/media/photo" ]; environment = { # TODO }; }; jellyfin-vue = { hostname = "jellyfin-vue"; image = "ghcr.io/jellyfin/jellyfin-vue:unstable"; autoStart = true; ports = [ "8080:80/tcp" ]; extraOptions = [ "--network=${networkName}" ]; labels = { }; }; feishin = let feishinPort = "9180"; in { hostname = "feishin"; image = "ghcr.io/jeffvli/feishin:0.19.0"; autoStart = true; ports = [ "${feishinPort}:9180/tcp" # Web player (HTTP) ]; extraOptions = [ "--network=${networkName}" ]; environment = { # pre defined server name SERVER_NAME = "Hugo"; # When true AND name/type/url are set, only username/password can be toggled SERVER_LOCK = "true"; # Either "jellyfin" or "navidrome" SERVER_TYPE = "jellyfin"; # http://address:port SERVER_URL= "https://jelly.depeuter.dev"; TZ = config.time.timeZone; }; labels = { "traefik.enable" = "true"; "traefik.http.routers.feishin.rule" = "Host(`play.jelly.depeuter.dev`)"; "traefik.http.services.feishin.loadbalancer.server.port" = feishinPort; "traefik.tls.options.default.minVersion" = "VersionTLS13"; }; }; }; }; }