kubernetes-deployments/modules/media.nix
2024-12-21 13:57:19 +01:00

640 lines
15 KiB
Nix

{
globals,
config,
lib,
utils,
...
}: {
options.media.enable = lib.mkEnableOption "media";
config = lib.mkIf config.media.enable {
kubernetes.resources = {
deployments = {
jellyfin.spec = {
selector.matchLabels = {
app = "media";
component = "jellyfin";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "jellyfin";
};
spec = {
containers.jellyfin = {
image = globals.images.jellyfin;
ports.web.containerPort = 8096;
imagePullPolicy = "IfNotPresent";
env.JELLYFIN_PublishedServerUrl.value = "https://media.kun.is";
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
{
name = "media";
mountPath = "/media";
}
{
name = "cache";
mountPath = "/config/transcodes";
}
];
};
volumes = {
config.persistentVolumeClaim.claimName = "jellyfin";
cache.persistentVolumeClaim.claimName = "jellyfin-cache";
media.hostPath = {
path = "/mnt/longhorn/persistent/media";
type = "Directory";
};
};
securityContext = {
fsGroup = 0;
fsGroupChangePolicy = "OnRootMismatch";
};
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms = [
{
matchExpressions = [
{
key = "hasMedia";
operator = "In";
values = ["true"];
}
];
}
];
};
};
};
deluge.spec = {
selector.matchLabels = {
app = "media";
component = "deluge";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "deluge";
};
spec = {
containers.deluge = {
image = globals.images.deluge;
imagePullPolicy = "IfNotPresent";
env = {
PUID.value = "1000";
PGID.value = "1000";
TZ.value = "Europe/Amsterdam";
DELUGE_LOGLEVEL.value = "info";
};
ports = {
web.containerPort = 8112;
bittorrent.containerPort = 31780;
};
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
{
name = "media";
mountPath = "/media";
}
];
};
volumes = {
config.persistentVolumeClaim.claimName = "deluge";
media.persistentVolumeClaim.claimName = "media";
};
};
};
};
jellyseerr.spec = {
selector.matchLabels = {
app = "media";
component = "jellyseerr";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "jellyseerr";
};
spec = {
volumes.config.persistentVolumeClaim.claimName = "jellyseerr";
containers.jellyseerr = {
image = utils.mkNixNGImage "jellyseerr";
ports.web.containerPort = 5055;
imagePullPolicy = "IfNotPresent";
env = {
LOG_LEVEL.value = "debug";
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [
{
name = "config";
mountPath = "/app/config";
}
];
};
securityContext = {
fsGroup = 0;
fsGroupChangePolicy = "OnRootMismatch";
};
};
};
};
radarr.spec = {
selector.matchLabels = {
app = "media";
component = "radarr";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "radarr";
};
spec = {
containers.radarr = {
image = utils.mkNixNGImage "radarr";
ports.web.containerPort = 7878;
imagePullPolicy = "IfNotPresent";
env = {
PUID.value = "1000";
PGID.value = "1000";
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
{
name = "media";
mountPath = "/media";
}
];
};
volumes = {
config.persistentVolumeClaim.claimName = "radarr";
media.persistentVolumeClaim.claimName = "media";
};
securityContext = {
fsGroup = 1000;
fsGroupChangePolicy = "OnRootMismatch";
};
};
};
};
prowlarr.spec = {
selector.matchLabels = {
app = "media";
component = "prowlarr";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "prowlarr";
};
spec = {
volumes.config.persistentVolumeClaim.claimName = "prowlarr";
containers.prowlarr = {
image = globals.images.prowlarr;
ports.web.containerPort = 9696;
imagePullPolicy = "IfNotPresent";
env = {
PUID.value = "1000";
PGID.value = "1000";
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
];
};
securityContext = {
fsGroup = 1000;
fsGroupChangePolicy = "OnRootMismatch";
};
};
};
};
sonarr.spec = {
selector.matchLabels = {
app = "media";
component = "sonarr";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "sonarr";
};
spec = {
containers.sonarr = {
image = globals.images.sonarr;
ports.web.containerPort = 8989;
imagePullPolicy = "IfNotPresent";
env = {
PUID.value = "1000";
PGID.value = "1000";
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
{
name = "media";
mountPath = "/media";
}
];
};
volumes = {
config.persistentVolumeClaim.claimName = "sonarr";
media.persistentVolumeClaim.claimName = "media";
};
securityContext = {
fsGroup = 1000;
fsGroupChangePolicy = "OnRootMismatch";
};
};
};
};
bazarr.spec = {
selector.matchLabels = {
app = "media";
component = "bazarr";
};
strategy = {
type = "RollingUpdate";
rollingUpdate = {
maxSurge = 0;
maxUnavailable = 1;
};
};
template = {
metadata.labels = {
app = "media";
component = "bazarr";
};
spec = {
containers.bazarr = {
image = globals.images.bazarr;
ports.web.containerPort = 6767;
imagePullPolicy = "IfNotPresent";
env = {
PUID.value = "1000";
PGID.value = "1000";
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
{
name = "media";
mountPath = "/media";
}
];
};
volumes = {
config.persistentVolumeClaim.claimName = "bazarr";
media.persistentVolumeClaim.claimName = "media";
};
securityContext = {
fsGroup = 1000;
fsGroupChangePolicy = "OnRootMismatch";
};
};
};
};
};
services = {
jellyfin.spec = {
selector = {
app = "media";
component = "jellyfin";
};
ports.web = {
port = 80;
targetPort = "web";
};
};
deluge.spec = {
type = "LoadBalancer";
loadBalancerIP = globals.transmissionIPv4;
selector = {
app = "media";
component = "deluge";
};
ports = {
bittorrent = {
port = 31780;
targetPort = "bittorrent";
};
web = {
port = 80;
targetPort = "web";
};
};
};
jellyseerr.spec = {
type = "LoadBalancer";
loadBalancerIP = globals.jellyseerrIPv4;
selector = {
app = "media";
component = "jellyseerr";
};
ports.web = {
port = 80;
targetPort = "web";
};
};
radarr.spec = {
type = "LoadBalancer";
loadBalancerIP = globals.radarrIPv4;
selector = {
app = "media";
component = "radarr";
};
ports.web = {
port = 80;
targetPort = "web";
};
};
prowlarr.spec = {
type = "LoadBalancer";
loadBalancerIP = globals.prowlarrIPv4;
selector = {
app = "media";
component = "prowlarr";
};
ports.web = {
port = 80;
targetPort = "web";
};
};
sonarr.spec = {
type = "LoadBalancer";
loadBalancerIP = globals.sonarrIPv4;
selector = {
app = "media";
component = "sonarr";
};
ports.web = {
port = 80;
targetPort = "web";
};
};
bazarr.spec = {
type = "LoadBalancer";
loadBalancerIP = globals.bazarrIPv4;
selector = {
app = "media";
component = "bazarr";
};
ports.web = {
port = 80;
targetPort = "web";
};
};
};
persistentVolumeClaims = {
jellyfin-cache.spec = {
accessModes = ["ReadWriteOnce"];
resources.requests.storage = "20Gi";
};
media.spec = {
accessModes = ["ReadWriteMany"];
storageClassName = "";
resources.requests.storage = "1Mi";
volumeName = "media-media";
};
};
};
lab = {
ingresses = {
jellyfin = {
host = "media.kun.is";
service = {
name = "jellyfin";
portName = "web";
};
};
jellyseerr = {
host = "jellyseerr.kun.is";
entrypoint = "localsecure";
service = {
name = "jellyseerr";
portName = "web";
};
};
};
tailscaleIngresses = {
tailscale-jellyseerr = {
host = "jellyseerr";
service.name = "jellyseerr";
};
tailscale-radarr = {
host = "radarr";
service.name = "radarr";
};
tailscale-sonarr = {
host = "sonarr";
service.name = "sonarr";
};
tailscale-bazarr = {
host = "bazarr";
service.name = "bazarr";
};
tailscale-prowlarr = {
host = "prowlarr";
service.name = "prowlarr";
};
tailscale-deluge = {
host = "deluge";
service.name = "deluge";
};
};
longhorn.persistentVolumeClaim = {
jellyfin = {
volumeName = "jellyfin";
storage = "5Gi";
};
deluge = {
volumeName = "deluge";
storage = "500Mi";
};
jellyseerr = {
volumeName = "jellyseerr";
storage = "75Mi";
};
radarr = {
volumeName = "radarr";
storage = "300Mi";
};
prowlarr = {
volumeName = "prowlarr";
storage = "150Mi";
};
sonarr = {
volumeName = "sonarr";
storage = "150Mi";
};
bazarr = {
volumeName = "bazarr";
storage = "25Mi";
};
};
};
};
}