From 3b4e7d07a48bde032a163befd401d125ddfa2f7f Mon Sep 17 00:00:00 2001 From: soraefir Date: Thu, 14 May 2026 00:10:38 +0200 Subject: [PATCH] jellyfin setup script --- modules/server/containers/apps/jellyfin.nix | 63 +++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/modules/server/containers/apps/jellyfin.nix b/modules/server/containers/apps/jellyfin.nix index de1ccf1..8407f03 100644 --- a/modules/server/containers/apps/jellyfin.nix +++ b/modules/server/containers/apps/jellyfin.nix @@ -4,9 +4,6 @@ let image = pkgs.dockerTools.streamLayeredImage { # pkgs.dockerTools.buildImage{# name = pkgs.jellyfin.name; tag = pkgs.jellyfin.version; - contents = [ - pkgs.cacert - ]; config = { Entrypoint = [ "${pkgs.jellyfin}/bin/jellyfin" ]; ExposedPorts = { "8096/tcp" = { }; }; @@ -41,8 +38,10 @@ in { # secret = name; extraEnv = { DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = "1"; - # JELLYFIN_WEB_DIR = "${pkgs.jellyfin-web}/share/jellyfin-web"; + JELLYFIN_WEB_DIR = "${pkgs.jellyfin-web}/share/jellyfin-web"; 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" @@ -64,5 +63,61 @@ in { }; }; + setup = { + trigger = "server"; + envFile = config.sops.secrets."CUSTOM".path; + script = pkgs.writeShellScript "setup" '' + JELLYFIN_URL="http://jellyfin-server:8096" + until ${pkgs.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" = "true" ]; then + echo "Jellyfin wizard already completed. Exiting cleanly." + exit 0 + fi + + if ! ${pkgs.curl}/bin/curl -sSf -X POST "''\${JELLYFIN_URL}/Startup/Configuration" \ + -H "Content-Type: application/json" \ + -d '{"ServerName":"jellyfin","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}') + + echo "Payload to be sent to /Startup/User: ''${SETUP_USER_PAYLOAD}" + + 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 + + # Enable remote access, disable UPnP auto-mapping + 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 + + # Complete the wizard + 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!" + ''; + }; } \ No newline at end of file