un container

This commit is contained in:
mjallen18
2025-10-09 17:48:27 -05:00
parent ef22231dd7
commit 76c0cd98d8
9 changed files with 388 additions and 147 deletions

View File

@@ -8,68 +8,40 @@
with lib;
let
cfg = config.${namespace}.services.actual;
dataDir = "/data";
hostAddress = "10.0.1.3";
actualUserId = config.users.users.nix-apps.uid;
actualGroupId = config.users.groups.jallen-nas.gid;
actualConfig = {
services.actual = {
enable = true;
openFirewall = true;
settings = {
trustedProxies = [ hostAddress ];
trustedProxies = [ "10.0.1.3" ];
port = cfg.port;
dataDir = dataDir;
serverFiles = "${dataDir}/server-files";
userFiles = "${dataDir}/user-files";
dataDir = cfg.dataDir;
serverFiles = "${cfg.dataDir}/server-files";
userFiles = "${cfg.dataDir}/user-files";
};
};
users.users.actual = {
isSystemUser = true;
uid = lib.mkForce actualUserId;
group = "actual";
};
users.groups = {
actual = {
gid = lib.mkForce actualGroupId;
};
};
# System packages
environment.systemPackages = with pkgs; [
sqlite
];
# Create and set permissions for required directories
system.activationScripts.actual-dirs = ''
mkdir -p ${dataDir}
chown -R actual:actual ${dataDir}
chmod -R 0700 ${dataDir}
'';
systemd.services = {
actual = {
environment.ACTUAL_CONFIG_PATH = lib.mkForce "${dataDir}/config.json";
environment.ACTUAL_CONFIG_PATH = lib.mkForce "${cfg.dataDir}/config.json";
serviceConfig = {
ExecStart = lib.mkForce "${lib.getExe pkgs.actual-server} --config ${dataDir}/config.json";
WorkingDirectory = lib.mkForce dataDir;
StateDirectory = lib.mkForce dataDir;
ExecStart = lib.mkForce "${lib.getExe pkgs.actual-server} --config ${cfg.dataDir}/config.json";
WorkingDirectory = lib.mkForce cfg.dataDir;
StateDirectory = lib.mkForce cfg.dataDir;
StateDirectoryMode = lib.mkForce 700;
DynamicUser = lib.mkForce false;
ProtectSystem = lib.mkForce null;
};
};
};
};
bindMounts = {
"${dataDir}" = {
hostPath = cfg.dataDir;
isReadOnly = false;
users.users.actual = {
isSystemUser = true;
group = "actual";
home = cfg.dataDir;
};
users.groups.actual = {};
};
# Create reverse proxy configuration using mkReverseProxy
@@ -80,22 +52,12 @@ let
middlewares = cfg.reverseProxy.middlewares;
};
actualContainer =
(lib.${namespace}.mkContainer {
name = "actual";
localAddress = cfg.localAddress;
ports = [ cfg.port ];
bindMounts = bindMounts;
config = actualConfig;
})
{ inherit lib; };
fullConfig = {
"${namespace}".services.traefik = lib.mkIf cfg.reverseProxy.enable {
reverseProxies = [ reverseProxyConfig ];
};
}
// actualContainer;
// actualConfig;
in
{
imports = [ ./options.nix ];

View File

@@ -0,0 +1,104 @@
{
config,
pkgs,
lib,
namespace,
...
}:
with lib;
let
cfg = config.${namespace}.services.actual;
dataDir = "/data";
hostAddress = "10.0.1.3";
actualUserId = config.users.users.nix-apps.uid;
actualGroupId = config.users.groups.jallen-nas.gid;
actualConfig = {
services.actual = {
enable = true;
openFirewall = true;
settings = {
trustedProxies = [ hostAddress ];
port = cfg.port;
dataDir = dataDir;
serverFiles = "${dataDir}/server-files";
userFiles = "${dataDir}/user-files";
};
};
users.users.actual = {
isSystemUser = true;
uid = lib.mkForce actualUserId;
group = "actual";
};
users.groups = {
actual = {
gid = lib.mkForce actualGroupId;
};
};
# System packages
environment.systemPackages = with pkgs; [
sqlite
];
# Create and set permissions for required directories
system.activationScripts.actual-dirs = ''
mkdir -p ${dataDir}
chown -R actual:actual ${dataDir}
chmod -R 0700 ${dataDir}
'';
systemd.services = {
actual = {
environment.ACTUAL_CONFIG_PATH = lib.mkForce "${dataDir}/config.json";
serviceConfig = {
ExecStart = lib.mkForce "${lib.getExe pkgs.actual-server} --config ${dataDir}/config.json";
WorkingDirectory = lib.mkForce dataDir;
StateDirectory = lib.mkForce dataDir;
StateDirectoryMode = lib.mkForce 700;
DynamicUser = lib.mkForce false;
ProtectSystem = lib.mkForce null;
};
};
};
};
bindMounts = {
"${dataDir}" = {
hostPath = cfg.dataDir;
isReadOnly = false;
};
};
# Create reverse proxy configuration using mkReverseProxy
reverseProxyConfig = lib.${namespace}.mkReverseProxy {
name = "actual";
subdomain = cfg.reverseProxy.subdomain;
url = "http://${cfg.localAddress}:${toString cfg.port}";
middlewares = cfg.reverseProxy.middlewares;
};
actualContainer =
(lib.${namespace}.mkContainer {
name = "actual";
localAddress = cfg.localAddress;
ports = [ cfg.port ];
bindMounts = bindMounts;
config = actualConfig;
})
{ inherit lib; };
fullConfig = {
"${namespace}".services.traefik = lib.mkIf cfg.reverseProxy.enable {
reverseProxies = [ reverseProxyConfig ];
};
}
// actualContainer;
in
{
imports = [ ./options.nix ];
config = mkIf cfg.enable fullConfig;
}

88
modules/nixos/services/jellyseerr/default.nix Executable file → Normal file
View File

@@ -6,78 +6,46 @@
}:
with lib;
let
inherit (lib.${namespace}) mkOpt mkReverseProxyOpt;
cfg = config.${namespace}.services.jellyseerr;
jellyseerrPort = 5055;
dataDir = "/var/lib/private/jellyseerr";
in
{
imports = [ ./options.nix ];
options.${namespace}.services.jellyseerr = {
enable = mkEnableOption "enable jellyseerr";
port = mkOpt types.int 5055 "jellyseerr port";
dataDir = mkOpt types.str "" "data dir";
};
config = mkIf cfg.enable {
containers.jellyseerr = {
autoStart = true;
privateNetwork = true;
hostAddress = "10.0.1.3";
localAddress = "10.0.1.52";
hostAddress6 = "fc00::1";
localAddress6 = "fc00::4";
# Enable jellyseerr service
services.jellyseerr = {
enable = true;
port = cfg.port;
openFirewall = true;
configDir = cfg.dataDir;
};
bindMounts = {
${dataDir} = {
hostPath = "/media/nas/main/nix-app-data/jellyseerr";
isReadOnly = false;
systemd.services = {
jellyseerr = {
serviceConfig = {
WorkingDirectory = lib.mkForce cfg.dataDir;
StateDirectory = lib.mkForce cfg.dataDir;
StateDirectoryMode = lib.mkForce 700;
DynamicUser = lib.mkForce false;
ProtectSystem = lib.mkForce null;
};
};
config =
{
lib,
...
}:
{
# Enable jellyseerr service
services.jellyseerr = {
enable = true;
port = jellyseerrPort;
# package = package;
openFirewall = true;
};
networking = {
firewall = {
enable = true;
allowedTCPPorts = [ jellyseerrPort ];
};
# Use systemd-resolved inside the container
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
useHostResolvConf = lib.mkForce false;
};
# Create and set permissions for required directories
system.activationScripts.jellyseerr-dirs = ''
mkdir -p /var/lib/private/jellyseerr
chown -R jellyseerr:jellyseerr /var/lib/private/jellyseerr
chmod -R 775 /var/lib/private/jellyseerr
ln -sf /var/lib/private/jellyseerr /var/lib/jellyfin
'';
services.resolved.enable = true;
system.stateVersion = "23.11";
};
};
networking.nat = {
forwardPorts = [
{
destination = "10.0.1.52:5055";
sourcePort = jellyseerrPort;
}
];
users.users.jellyseerr = {
isSystemUser = true;
group = "jellyseerr";
home = cfg.dataDir;
};
users.groups.jellyseerr = {};
};
}

View File

@@ -0,0 +1,83 @@
{
config,
lib,
namespace,
...
}:
with lib;
let
cfg = config.${namespace}.services.jellyseerr;
jellyseerrPort = 5055;
dataDir = "/var/lib/private/jellyseerr";
in
{
imports = [ ./options.nix ];
config = mkIf cfg.enable {
containers.jellyseerr = {
autoStart = true;
privateNetwork = true;
hostAddress = "10.0.1.3";
localAddress = "10.0.1.52";
hostAddress6 = "fc00::1";
localAddress6 = "fc00::4";
bindMounts = {
${dataDir} = {
hostPath = "/media/nas/main/nix-app-data/jellyseerr";
isReadOnly = false;
};
};
config =
{
lib,
...
}:
{
# Enable jellyseerr service
services.jellyseerr = {
enable = true;
port = jellyseerrPort;
# package = package;
openFirewall = true;
};
networking = {
firewall = {
enable = true;
allowedTCPPorts = [ jellyseerrPort ];
};
# Use systemd-resolved inside the container
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
useHostResolvConf = lib.mkForce false;
};
# Create and set permissions for required directories
system.activationScripts.jellyseerr-dirs = ''
mkdir -p /var/lib/private/jellyseerr
chown -R jellyseerr:jellyseerr /var/lib/private/jellyseerr
chmod -R 775 /var/lib/private/jellyseerr
ln -sf /var/lib/private/jellyseerr /var/lib/jellyfin
'';
services.resolved.enable = true;
system.stateVersion = "23.11";
};
};
networking.nat = {
forwardPorts = [
{
destination = "10.0.1.52:5055";
sourcePort = jellyseerrPort;
}
];
};
};
}

View File

@@ -19,62 +19,52 @@ let
base-url = "https://${cfg.reverseProxy.subdomain}.mjallen.dev";
enable-login = true;
listen-http = ":${toString cfg.port}";
cache-file = "/var/lib/ntfy-sh/cache.db";
attachment-cache-dir = "/var/lib/ntfy-sh/attachments";
cache-file = "${cfg.dataDir}/cache.db";
attachment-cache-dir = "/${cfg.dataDir}/attachments";
behind-proxy = true;
auth-default-access = "deny-all";
auth-file = "/var/lib/ntfy-sh/user.db";
auth-file = "${cfg.dataDir}/user.db";
auth-users = [
"mjallen:$2a$10$g4TqI8UiKKVaKTmrwnXIw.wtajiLBM6oc3UCfJ//lPZFilJnBirn.:admin"
];
};
};
};
# Create and set permissions for required directories
system.activationScripts.ntfy-dirs = ''
mkdir -p /var/lib/ntfy-sh
chown -R ntfy-sh:ntfy-sh /var/lib/ntfy-sh
chmod -R 775 /var/lib/ntfy-sh
'';
};
bindMounts = {
"/var/lib/ntfy-sh" = {
hostPath = cfg.dataDir;
isReadOnly = false;
systemd.services = {
ntfy-sh = {
serviceConfig = {
WorkingDirectory = lib.mkForce cfg.dataDir;
StateDirectory = lib.mkForce cfg.dataDir;
StateDirectoryMode = lib.mkForce 700;
DynamicUser = lib.mkForce false;
ProtectSystem = lib.mkForce null;
};
};
};
"/run/.env" = {
hostPath = ntfyEnvFile;
isReadOnly = true;
users.users.ntfy-sh = {
isSystemUser = true;
group = "ntfy-sh";
home = cfg.dataDir;
};
users.groups.ntfy-sh = {};
};
# Create reverse proxy configuration using mkReverseProxy
reverseProxyConfig = lib.${namespace}.mkReverseProxy {
name = "ntfy";
subdomain = cfg.reverseProxy.subdomain;
url = "http://${cfg.localAddress}:${toString cfg.port}";
url = "http://10.0.1.3:${toString cfg.port}";
middlewares = cfg.reverseProxy.middlewares;
};
ntfyContainer =
(lib.${namespace}.mkContainer {
name = "ntfy";
localAddress = cfg.localAddress;
ports = [ cfg.port ];
bindMounts = bindMounts;
config = ntfyConfig;
})
{ inherit lib; };
fullConfig = {
${namespace}.services.traefik = lib.mkIf cfg.reverseProxy.enable {
"${namespace}".services.traefik = lib.mkIf cfg.reverseProxy.enable {
reverseProxies = [ reverseProxyConfig ];
};
}
// ntfyContainer;
// ntfyConfig;
in
with lib;
{

View File

@@ -0,0 +1,94 @@
{
config,
lib,
namespace,
...
}:
let
inherit (lib.${namespace}) mkOpt mkReverseProxyOpt;
cfg = config.${namespace}.services.ntfy;
ntfyEnvFile = config.sops.secrets."jallen-nas/ntfy/auth-users".path;
ntfyConfig = {
services = {
ntfy-sh = {
enable = true;
# environmentFile = "/run/.env";
settings = {
base-url = "https://${cfg.reverseProxy.subdomain}.mjallen.dev";
enable-login = true;
listen-http = ":${toString cfg.port}";
cache-file = "/var/lib/ntfy-sh/cache.db";
attachment-cache-dir = "/var/lib/ntfy-sh/attachments";
behind-proxy = true;
auth-default-access = "deny-all";
auth-file = "/var/lib/ntfy-sh/user.db";
auth-users = [
"mjallen:$2a$10$g4TqI8UiKKVaKTmrwnXIw.wtajiLBM6oc3UCfJ//lPZFilJnBirn.:admin"
];
};
};
};
# Create and set permissions for required directories
system.activationScripts.ntfy-dirs = ''
mkdir -p /var/lib/ntfy-sh
chown -R ntfy-sh:ntfy-sh /var/lib/ntfy-sh
chmod -R 775 /var/lib/ntfy-sh
'';
};
bindMounts = {
"/var/lib/ntfy-sh" = {
hostPath = cfg.dataDir;
isReadOnly = false;
};
"/run/.env" = {
hostPath = ntfyEnvFile;
isReadOnly = true;
};
};
# Create reverse proxy configuration using mkReverseProxy
reverseProxyConfig = lib.${namespace}.mkReverseProxy {
name = "ntfy";
subdomain = cfg.reverseProxy.subdomain;
url = "http://${cfg.localAddress}:${toString cfg.port}";
middlewares = cfg.reverseProxy.middlewares;
};
ntfyContainer =
(lib.${namespace}.mkContainer {
name = "ntfy";
localAddress = cfg.localAddress;
ports = [ cfg.port ];
bindMounts = bindMounts;
config = ntfyConfig;
})
{ inherit lib; };
fullConfig = {
${namespace}.services.traefik = lib.mkIf cfg.reverseProxy.enable {
reverseProxies = [ reverseProxyConfig ];
};
}
// ntfyContainer;
in
with lib;
{
options.${namespace}.services.ntfy = {
enable = mkEnableOption "ntfy service";
port = mkOpt types.int 8008 "Port for ntfy to be hosted on";
localAddress = mkOpt types.str "127.0.0.1" "local address of the service";
dataDir = mkOpt types.str "" "Path to the data dir";
reverseProxy = mkReverseProxyOpt;
};
config = lib.mkIf cfg.enable fullConfig;
}

View File

@@ -66,7 +66,7 @@ let
hassUrl = "http://10.0.1.4:8123";
immichUrl = "http://${serverIp}:${toString config.services.immich.port}";
jellyfinUrl = "http://${serverIp}:8096";
jellyseerrUrl = "http://${config.containers.jellyseerr.localAddress}:${toString config.containers.jellyseerr.config.services.jellyseerr.port}";
jellyseerrUrl = "http://10.0.1.3:${toString config.services.jellyseerr.port}";
lubeloggerUrl = "http://${serverIp}:6754";
onlyofficeUrl = "http://${config.containers.nextcloud.localAddress}:${toString config.containers.nextcloud.config.services.onlyoffice.port}";
openWebUIUrl = "http://${serverIp}:8888";
@@ -243,6 +243,22 @@ in
};
dynamicConfigOptions = {
# udp = {
# services = {
# wireguard.loadBalancer.servers = [
# {
# url = "localhost:51820";
# }
# ];
# };
# routers = {
# wireguard = {
# entryPoints = [ "websecure" ];
# service = "wireguard";
# };
# };
# };
http = {
middlewares = {
authentik = {
@@ -330,6 +346,12 @@ in
}
];
actual.loadBalancer.servers = [
{
url = "http://10.0.1.3:3333";
}
];
authentik.loadBalancer.servers = [
{
url = authentikUrl;
@@ -413,6 +435,17 @@ in
tls.certResolver = "letsencrypt";
};
actual = {
entryPoints = [ "websecure" ];
rule = "Host(`actual.${domain}`)";
service = "actual";
middlewares = [
"crowdsec"
"whitelist-geoblock"
];
tls.certResolver = "letsencrypt";
};
authentik = {
entryPoints = [ "websecure" ];
rule = "Host(`authentik.${domain}`)";

View File

@@ -5,7 +5,10 @@
# Existing properly namespaced services
immich.enable = true;
jellyfin.enable = true;
jellyseerr.enable = true;
jellyseerr = {
enable = true;
dataDir = "/media/nas/main/nix-app-data/jellyseerr";
};
lubelogger.enable = true;
nextcloud.enable = true;
ai.enable = true;

View File

@@ -24,12 +24,16 @@
enable = true;
package = pkgs.postgresql_16;
dataDir = "/media/nas/main/nix-app-data/postgresql";
ensureDatabases = [ "authentik" ];
ensureDatabases = [ "authentik" "homeassistant" ];
ensureUsers = [
{
name = "authentik";
ensureDBOwnership = true;
}
{
name = "homeassistant";
ensureDBOwnership = true;
}
];
};