Compare commits

...

5 commits

7 changed files with 247 additions and 24 deletions

View file

@ -3,7 +3,10 @@
{ {
config = { config = {
homelab = { homelab = {
apps.changedetection.enable = true; apps = {
calibre.enable = true;
traefik.enable = true;
};
virtualisation.guest.enable = true; virtualisation.guest.enable = true;
}; };

View file

@ -243,7 +243,7 @@ in {
port = 6767; port = 6767;
in lib.mkIf cfg.bazarr.enable { in lib.mkIf cfg.bazarr.enable {
hostname = "bazarr"; hostname = "bazarr";
image = "ghcr.io/hotio/bazarr:release-1.4.4"; image = "ghcr.io/hotio/bazarr:release-1.5.2";
autoStart = true; autoStart = true;
ports = lib.mkIf cfg.bazarr.exposePorts [ ports = lib.mkIf cfg.bazarr.exposePorts [
"${toString port}:${toString port}/tcp" "${toString port}:${toString port}/tcp"
@ -279,7 +279,7 @@ in {
port = 9696; port = 9696;
in lib.mkIf cfg.prowlarr.enable { in lib.mkIf cfg.prowlarr.enable {
hostname = "prowlarr"; hostname = "prowlarr";
image = "ghcr.io/hotio/prowlarr:release-1.23.1.4708"; image = "ghcr.io/hotio/prowlarr:release-2.0.5.5160";
autoStart = true; autoStart = true;
ports = lib.mkIf cfg.prowlarr.exposePorts [ ports = lib.mkIf cfg.prowlarr.exposePorts [
"${toString port}:${toString port}/tcp" "${toString port}:${toString port}/tcp"
@ -310,7 +310,7 @@ in {
port = 10095; port = 10095;
in lib.mkIf cfg.qbittorrent.enable { in lib.mkIf cfg.qbittorrent.enable {
hostname = "qbittorrent"; hostname = "qbittorrent";
image = "ghcr.io/hotio/qbittorrent:release-4.6.7"; image = "ghcr.io/hotio/qbittorrent:release-5.1.2";
autoStart = true; autoStart = true;
ports = lib.mkIf cfg.qbittorrent.exposePorts [ ports = lib.mkIf cfg.qbittorrent.exposePorts [
"${toString port}:${toString port}/tcp" "${toString port}:${toString port}/tcp"
@ -343,7 +343,7 @@ in {
port = 7878; port = 7878;
in lib.mkIf cfg.radarr.enable { in lib.mkIf cfg.radarr.enable {
hostname = "radarr"; hostname = "radarr";
image = "ghcr.io/hotio/radarr:release-5.9.1.9070"; image = "ghcr.io/hotio/radarr:testing-5.28.0.10205";
autoStart = true; autoStart = true;
ports = lib.mkIf cfg.radarr.exposePorts [ ports = lib.mkIf cfg.radarr.exposePorts [
"${toString port}:${toString port}/tcp" "${toString port}:${toString port}/tcp"
@ -377,7 +377,7 @@ in {
port = 8989; port = 8989;
in lib.mkIf cfg.sonarr.enable { in lib.mkIf cfg.sonarr.enable {
hostname = "sonarr"; hostname = "sonarr";
image = "ghcr.io/hotio/sonarr:release-4.0.9.2244"; image = "ghcr.io/hotio/sonarr:release-4.0.15.2941";
autoStart = true; autoStart = true;
ports = lib.mkIf cfg.sonarr.exposePorts [ ports = lib.mkIf cfg.sonarr.exposePorts [
"${toString port}:${toString port}/tcp" "${toString port}:${toString port}/tcp"

View file

@ -11,6 +11,7 @@ let
calibre-web-config = "/srv/calibre-web-config"; calibre-web-config = "/srv/calibre-web-config";
networkName = "calibre"; networkName = "calibre";
proxyNet = config.homelab.apps.traefik.sharedNetworkName;
in { in {
options.homelab.apps.calibre = { options.homelab.apps.calibre = {
enable = lib.mkEnableOption "Calibre (Desktop + Web)"; enable = lib.mkEnableOption "Calibre (Desktop + Web)";
@ -92,7 +93,7 @@ in {
innerPort = 8080; innerPort = 8080;
in { in {
hostname = "calibre"; hostname = "calibre";
image = "lscr.io/linuxserver/calibre:8.5.0"; image = "lscr.io/linuxserver/calibre:v8.10.0-ls354";
autoStart = true; autoStart = true;
ports = [ ports = [
# Open ports if you don't use Traefik # Open ports if you don't use Traefik
@ -102,6 +103,7 @@ in {
]; ];
extraOptions = [ extraOptions = [
"--network=${networkName}" "--network=${networkName}"
"--network=${proxyNet}"
# syscalls are unkown to Docker # syscalls are unkown to Docker
#"--security-opt" "seccomp=unconfined" #"--security-opt" "seccomp=unconfined"
@ -122,6 +124,7 @@ in {
]; ];
labels = { labels = {
"traefik.enable" = "true"; "traefik.enable" = "true";
"traefik.docker.network" = proxyNet;
"traefik.http.routers.calibre.rule" = "Host(`calibre.depeuter.dev`)"; "traefik.http.routers.calibre.rule" = "Host(`calibre.depeuter.dev`)";
"traefik.http.services.calibre.loadbalancer.server.port" = toString innerPort; "traefik.http.services.calibre.loadbalancer.server.port" = toString innerPort;
}; };
@ -148,7 +151,7 @@ in {
innerPort = 8083; innerPort = 8083;
in { in {
hostname = "calibre-web"; hostname = "calibre-web";
image = "lscr.io/linuxserver/calibre-web:0.6.24"; image = "lscr.io/linuxserver/calibre-web:0.6.25-ls346";
autoStart = true; autoStart = true;
ports = [ ports = [
# Open ports if you don't use Traefik # Open ports if you don't use Traefik
@ -156,6 +159,7 @@ in {
]; ];
extraOptions = [ extraOptions = [
"--network=${networkName}" "--network=${networkName}"
"--network=${proxyNet}"
]; ];
environment = { environment = {
inherit PUID PGID; inherit PUID PGID;
@ -175,6 +179,7 @@ in {
]; ];
labels = { labels = {
"traefik.enable" = "true"; "traefik.enable" = "true";
"traefik.docker.network" = proxyNet;
"traefik.http.routers.calibre-web.rule" = "Host(`books.depeuter.dev`)"; "traefik.http.routers.calibre-web.rule" = "Host(`books.depeuter.dev`)";
"traefik.http.services.calibre-web.loadbalancer.server.port" = toString innerPort; "traefik.http.services.calibre-web.loadbalancer.server.port" = toString innerPort;
}; };

View file

@ -10,6 +10,7 @@
./plex ./plex
./speedtest ./speedtest
./technitium-dns ./technitium-dns
./traefik
./vaultwarden ./vaultwarden
]; ];
} }

View file

@ -4,6 +4,7 @@ let
cfg = config.homelab.apps.jellyfin; cfg = config.homelab.apps.jellyfin;
networkName = "jellyfin"; networkName = "jellyfin";
inherit (config.homelab.fileSystems) media;
UID = 3008; UID = 3008;
GID = config.users.groups.media.gid; GID = config.users.groups.media.gid;
@ -12,6 +13,11 @@ in {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
homelab = { homelab = {
fileSystems.media.video = {
enable = true;
permissions = [ "read" ];
};
users = { users = {
apps.enable = true; apps.enable = true;
media.enable = true; media.enable = true;
@ -32,18 +38,6 @@ in {
]; ];
}; };
"/srv/video" = {
device = "192.168.0.11:/mnt/SMALL/MEDIA/VIDEO";
fsType = "nfs";
options = [
"ro"
"nfsvers=4.2"
"async" "soft"
"timeo=100" "retry=50" "actimeo=1800" "lookupcache=all"
"nosuid" "tcp"
];
};
"/srv/homevideo" = { "/srv/homevideo" = {
device = "192.168.0.11:/mnt/BIG/MEDIA/HOMEVIDEO/ARCHIVE"; device = "192.168.0.11:/mnt/BIG/MEDIA/HOMEVIDEO/ARCHIVE";
fsType = "nfs"; fsType = "nfs";
@ -101,7 +95,7 @@ in {
virtualisation.oci-containers.containers = { virtualisation.oci-containers.containers = {
jellyfin = { jellyfin = {
hostname = "jellyfin"; hostname = "jellyfin";
image = "jellyfin/jellyfin:10.10.0"; image = "jellyfin/jellyfin:10.10.7";
user = "${toString UID}:${toString GID}"; user = "${toString UID}:${toString GID}";
autoStart = true; autoStart = true;
ports = [ ports = [
@ -117,7 +111,7 @@ in {
"cache:/cache" "cache:/cache"
"/srv/audio:/media/audio" "/srv/audio:/media/audio"
"/srv/video:/media/video" "${media.video.hostPath}:/media/video"
"/srv/homevideo:/media/homevideo" "/srv/homevideo:/media/homevideo"
"/srv/photo:/media/photo" "/srv/photo:/media/photo"
]; ];
@ -144,7 +138,7 @@ in {
feishinPort = "9180"; feishinPort = "9180";
in { in {
hostname = "feishin"; hostname = "feishin";
image = "ghcr.io/jeffvli/feishin:0.7.1"; image = "ghcr.io/jeffvli/feishin:0.19.0";
autoStart = true; autoStart = true;
ports = [ ports = [
"${feishinPort}:9180/tcp" # Web player (HTTP) "${feishinPort}:9180/tcp" # Web player (HTTP)

View file

@ -0,0 +1,220 @@
{ config, lib, pkgs, ... }:
let
cfg = config.homelab.apps.penpot;
networkName = "penpot";
UID = config.users.users.apps.uid;
GID = config.users.groups.apps.gid;
version = "2.5.4";
srvPath = "/srv/penpot";
assetsPath = "/opt/data/assets";
PENPOT_FLAGS = "enable-smtp enable-prepl-server disable-secure-session-cookies disable-onboarding disable-registration";
# Max body size (30MiB); Used for plain requests, should never be
# greater than multi-part size
PENPOT_HTTP_SERVER_MAX_BODY_SIZE = "31457280";
# Max multipart body size (350MiB)
PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE = "367001600";
dbName = "penpot";
dbUser = "penpot";
dbPass = "penpot";
docker = config.virtualisation.oci-containers.containers;
in {
options.homelab.apps.penpot.enable = lib.mkEnableOption "Penpot using Docker";
config = lib.mkIf cfg.enable {
homelab = {
users.apps.enable = true;
virtualisation.containers.enable = true;
};
fileSystems."${srvPath}" = {
device = "192.168.0.11:/mnt/SMALL/CONFIG/PENPOT";
fsType = "nfs";
options = [
"rw"
"nfsvers=4.2"
"sync" "hard" "timeo=600"
"retrans=2"
"_netdev"
"nosuid" "tcp"
];
};
# Make sure the Docker network exists.
systemd.services."docker-${networkName}-create-network" = lib.mkIf cfg.enable {
description = "Create Docker network for ${networkName}";
requiredBy = [
"docker-penpot-frontend.service"
"docker-penpot-backend.service"
"docker-penpot-exporter.service"
"docker-penpot-postgres.service"
"docker-penpot-redis.service"
];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
if ! ${pkgs.docker}/bin/docker network ls | grep -q ${networkName}; then
${pkgs.docker}/bin/docker network create ${networkName}
fi
'';
};
virtualisation.oci-containers.containers = let
frontendPort = 8080;
redisUri = "redis://${docker.penpot-redis.hostname}/0";
in {
penpot-frontend = {
hostname = "penpot-frontend";
image = "penpotapp/frontend:${version}";
# user = "${toString UID}:${toString GID}";
user = "0:${toString GID}";
ports = [
# "9001:${toString frontendPort}/tcp"
];
extraOptions = [
"--network=${networkName}"
];
environment = {
inherit PENPOT_FLAGS;
inherit PENPOT_HTTP_SERVER_MAX_BODY_SIZE;
inherit PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE;
};
volumes = [
"${srvPath}:${assetsPath}"
];
dependsOn = [
docker.penpot-backend.hostname
docker.penpot-exporter.hostname
];
labels = {
"traefik.enable" = "true";
"traefik.http.routers.penpot.rule" = "Host(`penpot.depeuter.dev`)";
"traefik.http.services.penpot.loadbalancer.server.port" = toString frontendPort;
"traefik.tls.options.default.minVersion" = "VersionTLS13";
};
autoStart = true;
};
penpot-backend = {
hostname = "penpot-backend";
image = "penpotapp/backend:latest";
# user = "${toString UID}:${toString GID}";
user = "0:${toString GID}";
extraOptions = [
"--network=${networkName}"
];
environmentFiles = [
/home/admin/.penpot.secret
];
environment = {
inherit PENPOT_FLAGS;
inherit PENPOT_HTTP_SERVER_MAX_BODY_SIZE;
inherit PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE;
PENPOT_PUBLIC_URI = "https://penpot.depeuter.dev";
## Database connection parameters. Don't touch them unless you are using custom
## postgresql connection parameters.
PENPOT_DATABASE_URI = "postgresql://${docker.penpot-postgres.hostname}/${dbName}";
PENPOT_DATABASE_USERNAME = dbUser;
PENPOT_DATABASE_PASSWORD = dbPass;
## Redis is used for the websockets notifications. Don't touch unless the redis
## container has different parameters or different name.
PENPOT_REDIS_URI = redisUri;
## Default configuration for assets storage: using filesystem based with all files
## stored in a docker volume.
PENPOT_ASSETS_STORAGE_BACKEND = "assets-fs";
PENPOT_STORAGE_ASSETS_FS_DIRECTORY = assetsPath;
## Telemetry. When enabled, a periodical process will send anonymous data about this
## instance. Telemetry data will enable us to learn how the application is used,
## based on real scenarios. If you want to help us, please leave it enabled. You can
## audit what data we send with the code available on github.
PENPOT_TELEMETRY_ENABLED = "false";
PENPOT_TELEMETRY_REFERER = "compose";
# PENPOT_SMTP_HOST = "smtp.gmail.com";
# PENPOT_SMTP_PORT = "465";
# PENPOT_SMTP_USERNAME: "kmtl.hugo@gmail.com";
# PENPOT_SMTP_PASSWORD: <password>
# PENPOT_SMTP_TLS: true
};
volumes = [
"${srvPath}:${assetsPath}"
];
dependsOn = [
docker.penpot-postgres.hostname
docker.penpot-redis.hostname
];
autoStart = true;
};
penpot-exporter = {
hostname = "penpot-exporter";
image = "penpotapp/exporter:latest";
extraOptions = [
"--network=${networkName}"
];
environment = {
# Don't touch it; this uses an internal docker network to
# communicate with the frontend.
PENPOT_PUBLIC_URI = "http://${docker.penpot-frontend.hostname}:${toString frontendPort}";
## Redis is used for the websockets notifications.
PENPOT_REDIS_URI = redisUri;
};
dependsOn = [
docker.penpot-redis.hostname
];
autoStart = true;
};
penpot-postgres = {
hostname = "penpot-postgres";
image = "postgres:15";
extraOptions = [
"--network=${networkName}"
"--health-cmd='pg_isready -U ${dbUser}'"
"--health-interval=2s"
"--health-retries=5"
"--health-timeout=10s"
"--health-start-period=2s"
];
environment = {
POSTGRES_INITDB_ARGS = "--data-checksums";
POSTGRES_DB = dbName;
POSTGRES_USER = dbUser;
POSTGRES_PASSWORD = dbPass;
};
volumes = [
"penpot_postgres_v15:/var/lib/postgresql/data"
];
autoStart = true;
};
penpot-redis = {
hostname = "penpot-redis";
image = "redis:7.2";
extraOptions = [
"--network=${networkName}"
"--health-cmd='redis-cli ping | grep PONG'"
"--health-interval=1s"
"--health-retries=5"
"--health-timeout=3s"
"--health-start-period=3s"
];
autoStart = true;
};
};
};
}

View file

@ -44,6 +44,6 @@ in {
]; ];
}; };
}; };
}; };
} }