From bdb4ad8160557fa71321f30c995495216fc17ce0 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Wed, 1 Oct 2025 16:33:55 +0200 Subject: [PATCH 1/2] Updates --- modules/apps/arr/default.nix | 2 +- modules/apps/jellyfin/default.nix | 24 +++++++++--------------- modules/services/actions/default.nix | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/modules/apps/arr/default.nix b/modules/apps/arr/default.nix index 3b05429..e2c0df5 100644 --- a/modules/apps/arr/default.nix +++ b/modules/apps/arr/default.nix @@ -343,7 +343,7 @@ in { port = 7878; in lib.mkIf cfg.radarr.enable { hostname = "radarr"; - image = "ghcr.io/hotio/radarr:release-5.28.0.10205"; + image = "ghcr.io/hotio/radarr:testing-5.28.0.10205"; autoStart = true; ports = lib.mkIf cfg.radarr.exposePorts [ "${toString port}:${toString port}/tcp" diff --git a/modules/apps/jellyfin/default.nix b/modules/apps/jellyfin/default.nix index 5b4081a..011f56b 100644 --- a/modules/apps/jellyfin/default.nix +++ b/modules/apps/jellyfin/default.nix @@ -4,6 +4,7 @@ let cfg = config.homelab.apps.jellyfin; networkName = "jellyfin"; + inherit (config.homelab.fileSystems) media; UID = 3008; GID = config.users.groups.media.gid; @@ -12,6 +13,11 @@ in { config = lib.mkIf cfg.enable { homelab = { + fileSystems.media.video = { + enable = true; + permissions = [ "read" ]; + }; + users = { apps.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" = { device = "192.168.0.11:/mnt/BIG/MEDIA/HOMEVIDEO/ARCHIVE"; fsType = "nfs"; @@ -101,7 +95,7 @@ in { virtualisation.oci-containers.containers = { jellyfin = { hostname = "jellyfin"; - image = "jellyfin/jellyfin:10.10.0"; + image = "jellyfin/jellyfin:10.10.7"; user = "${toString UID}:${toString GID}"; autoStart = true; ports = [ @@ -117,7 +111,7 @@ in { "cache:/cache" "/srv/audio:/media/audio" - "/srv/video:/media/video" + "${media.video.hostPath}:/media/video" "/srv/homevideo:/media/homevideo" "/srv/photo:/media/photo" ]; @@ -144,7 +138,7 @@ in { feishinPort = "9180"; in { hostname = "feishin"; - image = "ghcr.io/jeffvli/feishin:0.7.1"; + image = "ghcr.io/jeffvli/feishin:0.19.0"; autoStart = true; ports = [ "${feishinPort}:9180/tcp" # Web player (HTTP) diff --git a/modules/services/actions/default.nix b/modules/services/actions/default.nix index 338b963..ea6b025 100644 --- a/modules/services/actions/default.nix +++ b/modules/services/actions/default.nix @@ -44,6 +44,6 @@ in { ]; }; }; - }; } + From da3157c8188b08a6b4d4147ea2e3138d4a71608c Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Wed, 1 Oct 2025 16:34:55 +0200 Subject: [PATCH 2/2] feat(penpot): Add module --- modules/apps/penpot/default.nix | 220 ++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 modules/apps/penpot/default.nix diff --git a/modules/apps/penpot/default.nix b/modules/apps/penpot/default.nix new file mode 100644 index 0000000..0ec01cd --- /dev/null +++ b/modules/apps/penpot/default.nix @@ -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: + # 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; + }; + }; + }; +}