130 lines
4.2 KiB
Nix
130 lines
4.2 KiB
Nix
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
|
let
|
|
serverCfg = config.syscfg.server;
|
|
image = pkgs.dockerTools.streamLayeredImage { # pkgs.dockerTools.buildImage{#
|
|
name = pkgs.jellyfin.name;
|
|
tag = pkgs.jellyfin.version;
|
|
contents = [ pkgs.cacert ];
|
|
config = {
|
|
User = "1000:1000";
|
|
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_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"
|
|
];
|
|
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" = "true" ]; then
|
|
echo "Jellyfin wizard already completed. Exiting cleanly."
|
|
exit 0
|
|
fi
|
|
|
|
#USE CONFIGURATION ENDPOINT
|
|
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
|
|
|
|
#USE AUTH ENDPOINT
|
|
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 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!"
|
|
'';
|
|
};
|
|
|
|
} |