{ config, containerCfg, pkgs, lib, builder, name, ... }: let serverCfg = config.syscfg.server; nss = pkgs.dockerTools.fakeNss.override { extraPasswdLines = [ "jellyfin:x:1000:1000:Jellyfin Daemon:/config/data:/bin/false" ]; extraGroupLines = [ "jellyfin:x:1000:" ]; }; image = pkgs.dockerTools.buildImage{#pkgs.dockerTools.streamLayeredImage { # name = pkgs.jellyfin.name; tag = pkgs.jellyfin.version; contents = [ pkgs.cacert nss pkgs.jellyfin pkgs.bashInteractive ]; config = { User = "jellyfin:jellyfin"; Entrypoint = [ "${pkgs.jellyfin}/bin/jellyfin" ]; ExposedPorts = { "8096/tcp" = { }; }; Env = [ "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" "NIX_SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" ]; }; }; #LDAP_DC_DOMAIN = "dc=ldap,dc=helcel,dc=net" #HOST=... #LDAP_BIND_USER=ldap-sa #LDAP_BIND_PASSWORD=... #LDAP_GROUP=flix #LDAP_ADMIN=admin in { paths = [ { path = "${serverCfg.dataPath}/media/"; owner = "1000:1000"; mode = "0755"; } { path = "${serverCfg.configPath}/jellyfin/"; owner = "1000:1000"; mode = "0755"; } ]; containers = { server = builder.mkContainer { subdomain = containerCfg.subdomain; #imageStream = image; imageFile = image; port = 8096; extraEnv = { HOME = "/config/data"; DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = "1"; JELLYFIN_HttpListenerHost__BindAddress= "0.0.0.0"; #we can use settings.xml override JELLYFIN_ServerName = if containerCfg.extra?name then containerCfg.extra.name else "Flix"; }; extraOptions = [ "--tmpfs=/tmp:rw,noexec,nosuid,size=512m" ]; overrides = { cmd = [ "--datadir" "/config/data" "--cachedir" "/config/cache" "--configdir" "/config/config" "--logdir" "/config/log" ]; volumes = [ "${serverCfg.dataPath}/media:/media:ro" "${serverCfg.configPath}/jellyfin:/config" ]; # If you have an Intel/AMD GPU for transcoding, add the device: devices = lib.optionals (builtins.pathExists "/dev/dri") [ "/dev/dri:/dev/dri" ]; }; }; }; setup = { trigger = "server"; envFile = config.sops.secrets."CUSTOM".path; script = pkgs.writeShellScript "setup" '' JELLYFIN_URL="https://${containerCfg.subdomain}.${serverCfg.hostDomain}" until ${pkgs.curl}/bin/curl -sf "$JELLYFIN_URL/health" > /dev/null 2>&1; do sleep 5 done echo "Jellyfin is up. Sleeping for 20 seconds..." sleep 20 WIZARD_COMPLETE=$(${pkgs.curl}/bin/curl -sSf "$JELLYFIN_URL/System/Info/Public" 2>/dev/null | \ ${pkgs.jq}/bin/jq -r '.StartupWizardCompleted // false') if [ "$WIZARD_COMPLETE" = "false" ]; then if ! ${pkgs.curl}/bin/curl -sSf -X POST "$JELLYFIN_URL/Startup/Configuration" \ -H "Content-Type: application/json" \ -d '{"ServerName":"Flix","UICulture":"en-US","MetadataCountryCode":"US","PreferredMetadataLanguage":"en"}'; then echo "ERROR: Failed to set startup configuration." exit 1 fi SETUP_USER_PAYLOAD=$(${pkgs.jq}/bin/jq -n \ --arg name "$DEFAULT_ADMIN_USERNAME" \ --arg pass "$DEFAULT_ADMIN_PASSWORD" \ '{"Name": $name, "Password": $pass}') if ! ${pkgs.curl}/bin/curl -sSf -X GET "$JELLYFIN_URL/Startup/User"; then echo "ERROR: Failed to get base user." exit 1 fi if ! ${pkgs.curl}/bin/curl -sSf -X POST "$JELLYFIN_URL/Startup/User" \ -H 'accept: */*' \ -H "Content-Type: application/json" \ -d "$SETUP_USER_PAYLOAD"; then echo "ERROR: Failed to set admin user." exit 1 fi if ! ${pkgs.curl}/bin/curl -sSf -X POST "$JELLYFIN_URL/Startup/RemoteAccess" \ -H "Content-Type: application/json" \ -d '{"EnableRemoteAccess":true,"EnableAutomaticPortMapping":false}'; then echo "ERROR: Failed to configure remote access." exit 1 fi if ! ${pkgs.curl}/bin/curl -sSf -X POST "''$JELLYFIN_URL/Startup/Complete"; then echo "ERROR: Failed to complete wizard." exit 1 fi echo "Jellyfin initialization successfully completed!" fi JELLYFIN_TOKEN=$(${pkgs.curl}/bin/curl -sSf -X POST "$JELLYFIN_URL/Users/AuthenticateByName" \ -H "Content-Type: application/json" \ -H "Authorization: MediaBrowser Client=\"Bash Script\", Device=\"Server Terminal\", DeviceId=\"script-12345\", Version=\"1.0.0\"" \ -d "{\"Username\": \"$DEFAULT_ADMIN_USERNAME\", \"Pw\": \"$DEFAULT_ADMIN_PASSWORD\"}" \ | ${pkgs.jq}/bin/jq -r '.AccessToken') # Verify we got a token if [ "$JELLYFIN_TOKEN" = "null" ] || [ -z "$JELLYFIN_TOKEN" ]; then echo "ERROR: Authentication failed." exit 1 fi if ! ${pkgs.curl}/bin/curl -sSf -X POST "$JELLYFIN_URL/Packages/Installed/LDAP%20Authentication?assemblyGuid=958aad6637844d2ab89aa7b6fab6e25c" \ -H "Authorization: MediaBrowser Token=\"$JELLYFIN_TOKEN\"" \ -H "Content-Length: 0" echo "ERROR: LDAP Plugin Setup Failed." exit 1 fi echo "Completed Setup" ''; }; }