feat(refactor): WIP 2.0 some progress

This commit is contained in:
2025-10-13 21:13:53 +02:00
parent d2bd385367
commit 63f495fa0d
18 changed files with 653 additions and 612 deletions

View File

@@ -0,0 +1,18 @@
{
imports = [
./bazarr
./flaresolverr
./gitea
./homepage-dashboard
./jellyfin
./jellyseerr
./lidarr
./n8n
./nextcloud
./prowlarr
./radarr
./sonarr
./uptime-kuma
./vaultwarden
];
}

View File

@@ -1,4 +1,3 @@
# "inspired" by @jtojnar <3
{
config,
lib,
@@ -7,21 +6,23 @@
}: let
unit = "gitea";
cfg = config.server.services.${unit};
domain = "${cfg.subdomain}.${config.server.infra.www.url}";
in {
config = lib.mkIf cfg.enable {
age.secrets = {
giteaCloudflared.file = "${self}/secrets/giteaCloudflared.age";
};
age.secrets.giteaCloudflared.file = "${self}/secrets/giteaCloudflared.age";
server.infra = {
fail2ban = {
jails = {
gitea = {
serviceName = "gitea";
failRegex = ''.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>'';
};
};
fail2ban.jails.unit = {
serviceName = "${unit}";
failRegex = ''
.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).*
from <HOST>
'';
};
postgresql.databases = [
{database = unit;}
];
};
services = {
@@ -30,11 +31,11 @@ in {
tunnels.${cfg.cloudflared.tunnelId} = {
credentialsFile = cfg.cloudflared.credentialsFile;
default = "http_status:404";
ingress."${cfg.url}".service = "http://localhost:${toString cfg.port}";
ingress."${domain}".service = "http://localhost:${toString cfg.port}";
};
};
${unit} = {
gitea = {
enable = true;
appName = "cnix code forge";
@@ -46,63 +47,51 @@ in {
createDatabase = false;
};
lfs = {
enable = true;
};
lfs.enable = true;
settings = {
cors = {
ENABLED = true;
SCHEME = "https";
ALLOW_DOMAIN = cfg.url;
};
log = {
MODE = "console";
ALLOW_DOMAIN = domain;
};
log.MODE = "console";
mailer = {
ENABLED = false;
MAILER_TYPE = "sendmail";
FROM = "noreply+adam@cnst.dev";
SENDMAIL_PATH = "/run/wrappers/bin/sendmail";
};
picture = {
DISABLE_GRAVATAR = true;
};
picture.DISABLE_GRAVATAR = true;
repository = {
DEFAULT_BRANCH = "main";
DEFAULT_REPO_UNITS = "repo.code,repo.issues,repo.pulls";
DISABLE_DOWNLOAD_SOURCE_ARCHIVES = true;
};
indexer = {
REPO_INDEXER_ENABLED = true;
};
indexer.REPO_INDEXER_ENABLED = true;
oauth2_client = {
ENABLE_AUTO_REGISTRATION = true;
ACCOUNT_LINKING = "auto";
};
server = {
DOMAIN = cfg.url;
DOMAIN = domain;
LANDING_PAGE = "explore";
HTTP_PORT = cfg.port;
ROOT_URL = "https://${cfg.url}/";
};
security = {
DISABLE_GIT_HOOKS = false;
};
service = {
DISABLE_REGISTRATION = true;
};
session = {
COOKIE_SECURE = true;
ROOT_URL = "https://${domain}/";
};
security.DISABLE_GIT_HOOKS = false;
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
};
};
};
server.infra.postgresql.databases = [
{
database = "gitea";
}
];
};
}

View File

@@ -5,7 +5,7 @@
...
}: let
unit = "homepage-dashboard";
cfg = config.server.services.homepage-dashboard;
cfg = config.server.services.${unit};
srv = config.server;
in {
config = lib.mkIf cfg.enable {
@@ -14,11 +14,14 @@ in {
file = "${self}/secrets/homepageEnvironment.age";
};
};
services = {
glances.enable = true;
${unit} = {
enable = true;
environmentFile = config.age.secrets.homepageEnvironment.path;
settings = {
layout = [
{
@@ -53,10 +56,12 @@ in {
};
}
];
headerStyle = "clean";
statusStyle = "dot";
hideVersion = "true";
};
widgets = [
{
openmeteo = {
@@ -77,6 +82,7 @@ in {
};
}
];
services = let
homepageCategories = [
"Arr"
@@ -84,21 +90,30 @@ in {
"Downloads"
"Services"
];
hl = config.server.services;
homepageServices = x: (lib.attrsets.filterAttrs (
_name: value: value ? homepage && value.homepage.category == x
allServices = srv.services;
homepageServicesFor = category:
lib.filterAttrs
(
name: value:
name
!= unit
&& value ? homepage
&& value.homepage.category == category
)
srv.services);
allServices;
in
lib.lists.forEach homepageCategories (cat: {
"${cat}" =
lib.lists.forEach (lib.attrsets.mapAttrsToList (name: _value: name) (homepageServices "${cat}"))
lib.lists.forEach
(lib.attrsets.mapAttrsToList (name: _value: name) (homepageServicesFor cat))
(x: {
"${hl.${x}.homepage.name}" = {
icon = hl.${x}.homepage.icon;
description = hl.${x}.homepage.description;
href = "https://${hl.${x}.url}";
siteMonitor = "https://${hl.${x}.url}";
"${allServices.${x}.homepage.name}" = {
icon = allServices.${x}.homepage.icon;
description = allServices.${x}.homepage.description;
href = "https://${allServices.${x}.url}";
siteMonitor = "https://${allServices.${x}.url}";
};
});
})

View File

@@ -15,19 +15,15 @@ in {
nextcloudCloudflared.file = "${self}/secrets/nextcloudCloudflared.age";
};
server.infra.fail2ban = lib.mkIf srv.infra.fail2ban.enable {
jails = {
nextcloud = {
serviceName = "${unit}";
_groupsre = ''(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)'';
failRegex = ''
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
'';
datePattern = '',?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"'';
};
};
server.infra.fail2ban.jails.nextcloud = {
serviceName = "${unit}";
_groupsre = ''(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)'';
failRegex = ''
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
'';
datePattern = '',?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"'';
};
services = {

View File

@@ -7,7 +7,7 @@
}: let
unit = "vaultwarden";
cfg = config.server.services.${unit};
www = config.server.infra.www;
domain = "${cfg.subdomain}.${config.server.infra.www.url}";
in {
config = lib.mkIf cfg.enable {
age.secrets = {
@@ -15,15 +15,9 @@ in {
vaultwardenEnvironment.file = "${self}/secrets/vaultwardenEnvironment.age";
};
server.infra = {
fail2ban = {
jails = {
vaultwarden = {
serviceName = "${unit}";
failRegex = ''^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$'';
};
};
};
server.infra.fail2ban.jails.${unit} = {
serviceName = "${unit}";
failRegex = ''^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$'';
};
services = {
@@ -32,7 +26,7 @@ in {
tunnels.${cfg.cloudflared.tunnelId} = {
credentialsFile = cfg.cloudflared.credentialsFile;
default = "http_status:404";
ingress."${cfg.url}".service = "http://localhost:${toString cfg.port}";
ingress."${domain}".service = "http://localhost:${toString cfg.port}";
};
};
@@ -43,7 +37,7 @@ in {
backupDir = "/var/backup/vaultwarden";
config = {
DOMAIN = "https://vault.${www.url}";
DOMAIN = "https://${domain}";
SIGNUPS_ALLOWED = false;
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = cfg.port;