Merge branch 'master' into 2305

This commit is contained in:
Andreas Zweili 2023-06-06 23:28:08 +02:00
commit c785e6bcd1
33 changed files with 701 additions and 508 deletions

View File

@ -1,10 +1,11 @@
{ ... }:
{
imports = [
./common
./hardware/bluetooth
./hardware/dvd
./hardware/nvidia
./misc/common
./misc/username
./profiles/desktop
./programs/email
./programs/eog
@ -24,20 +25,29 @@
./services/grav
./services/haproxy
./services/heimdall
./services/logs-share
./services/log-to-ram
./services/logs-share
./services/mariadb-for-containers
./services/media-share
./services/nextcloud
./services/nginx-acme-base
./services/nginx-fpm
./services/nginx-proxy
./services/pipewire
./services/plex
./services/postgresql
./services/rclone-webdav
./services/rdp
./services/restic-client-desktop
./services/restic-client-server
./services/restic-client-server-mysql
./services/restic-client-server-postgres
./services/restic-server
./services/rss-bridge
./services/syslog
./services/telegram-notifications
./services/tlp
./services/ttrss-postgres
./services/virtualbox-guest
./username
];
}

View File

@ -1,29 +0,0 @@
{ dataDir, documentRoot ? "/var/www/html", domain, port ? "9000", }:
{ inputs, pkgs, ... }:
{
services = {
az-acme-base.enable = true;
nginx = {
appendHttpConfig = ''
index index.php;
'';
virtualHosts."${domain}" = {
enableACME = true;
forceSSL = true;
root = dataDir;
locations = {
"~ \\.php$" = {
extraConfig = ''
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME ${documentRoot}$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:${port};
'';
};
};
};
};
};
}

View File

@ -1,20 +0,0 @@
{ domain, port ? "8080" }: { inputs, ... }: {
services = {
az-acme-base.enable = true;
nginx = {
appendHttpConfig = ''
# Disable embedding as a frame
add_header X-Frame-Options DENY;
'';
recommendedProxySettings = true;
virtualHosts."${domain}" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${port}";
proxyWebsockets = true; # needed if you need to use WebSocket
};
};
};
};
}

View File

@ -1,46 +0,0 @@
{ config, inputs, ... }:
{
age.secrets.plexClaim.file = "${inputs.self}/scrts/plex_claim.age";
networking = {
firewall.allowedTCPPorts = [
32400 # Web Interface/ Remote Access
];
firewall.allowedUDPPorts = [
1900 # DLNA
5353 # Bonjour/Avahi
32410 # GDM network discovery
32412 # GDM network discovery
32413 # GDM network discovery
32414 # GDM network discovery
32469 # Plex DLNA Server
];
};
services.az-docker.enable = true;
virtualisation.oci-containers = {
backend = "docker";
containers."plex" = {
autoStart = true;
# https://fleet.linuxserver.io/image?name=linuxserver/plex
image = "lscr.io/linuxserver/plex:1.32.1";
environment = {
TZ = " Europe/Zurich ";
PUID = "1000";
PGID = "1000";
VERSION = "docker";
};
environmentFiles = [ config.age.secrets.plexClaim.path ];
volumes = [
"/var/lib/plex/config:/config"
"/var/lib/plex/tmp:/transcode"
"/etc/localtime:/etc/localtime:ro"
];
extraOptions = [
''--mount=type=volume,source=media,target=/mnt/media,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/media,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
"--network=host"
"--log-opt=tag='plex'"
];
};
};
}

View File

@ -1,9 +0,0 @@
{ pkgs, ... }:
{
services.postgresql = {
enable = true;
enableTCPIP = true;
settings.listen_addresses = pkgs.lib.mkForce "127.0.0.1,172.17.0.1";
};
networking.firewall.extraCommands = "iptables -A INPUT -p tcp --destination-port 5432 -s 172.16.0.0/12 -j ACCEPT";
}

View File

@ -1,56 +0,0 @@
{ path
, tag ? "home-dir"
, time
}: { config, inputs, pkgs, ... }:
{
services.az-telegram-notifications.enable = true;
age.secrets.resticKey.file = "${inputs.self}/scrts/restic.key.age";
systemd.timers."restic-backups" = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-backups.service" ];
timerConfig = {
OnCalendar = time;
};
};
systemd.services."restic-backups" = {
serviceConfig = {
User = "root";
Type = "oneshot";
};
environment = {
RESTIC_PASSWORD_FILE = config.age.secrets.resticKey.path;
RESTIC_REPOSITORY = "rest:http://10.7.89.30:8000";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic backup \
--exclude-file=${inputs.self}/modules/restic-client/excludes.txt \
--tag ${tag} ${path}
${pkgs.mariadb}/bin/mariabackup --backup --user=root --stream=xbstream | \
${pkgs.restic}/bin/restic backup \
--tag mariadb \
--stdin \
--stdin-filename mariadb.xb
${pkgs.restic}/bin/restic forget \
--tag home-dir \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
${pkgs.restic}/bin/restic forget \
--tag mariadb \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
'';
};
}

View File

@ -1,56 +0,0 @@
{ path
, tag ? "home-dir"
, time
}: { config, inputs, pkgs, ... }:
{
services.az-telegram-notifications.enable = true;
age.secrets.resticKey.file = "${inputs.self}/scrts/restic.key.age";
systemd.timers."restic-backups" = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-backups.service" ];
timerConfig = {
OnCalendar = time;
};
};
systemd.services."restic-backups" = {
serviceConfig = {
User = "root";
Type = "oneshot";
};
environment = {
RESTIC_PASSWORD_FILE = config.age.secrets.resticKey.path;
RESTIC_REPOSITORY = "rest:http://10.7.89.30:8000";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic backup \
--exclude-file=${inputs.self}/modules/restic-client/excludes.txt \
--tag ${tag} ${path}
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dumpall | \
${pkgs.restic}/bin/restic backup \
--tag postgres \
--stdin \
--stdin-filename all_databases.sql
${pkgs.restic}/bin/restic forget \
--tag home-dir \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
${pkgs.restic}/bin/restic forget \
--tag postgres \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
'';
};
}

View File

@ -1,42 +0,0 @@
{ path
, tag ? "home-dir"
, time
}: { config, inputs, pkgs, ... }:
{
services.az-telegram-notifications.enable = true;
age.secrets.resticKey.file = "${inputs.self}/scrts/restic.key.age";
systemd.timers."restic-backups" = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-backups.service" ];
timerConfig = {
OnCalendar = time;
};
};
systemd.services."restic-backups" = {
serviceConfig = {
User = "root";
Type = "oneshot";
};
environment = {
RESTIC_PASSWORD_FILE = config.age.secrets.resticKey.path;
RESTIC_REPOSITORY = "rest:http://10.7.89.30:8000";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic backup \
--exclude-file=${inputs.self}/modules/restic-client/excludes.txt \
--tag ${tag} ${path}
${pkgs.restic}/bin/restic forget \
--tag home-dir \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
'';
};
}

View File

@ -1,69 +0,0 @@
{ config, inputs, pkgs, ... }:
let
repository = "/var/lib/restic-server";
in
{
services.az-telegram-notifications.enable = true;
age.secrets.resticKey = {
file = "${inputs.self}/scrts/restic.key.age";
mode = "440";
owner = "restic";
group = "restic";
};
environment.systemPackages = with pkgs; [
restic
];
fileSystems."${repository}" = {
device = "10.7.89.108:restic-server";
fsType = "nfs";
options = [ "noatime" "hard" "nfsvers=4.0" ];
};
services.restic.server = {
enable = true;
dataDir = repository;
extraFlags = [ "--no-auth" ];
};
networking.firewall.allowedTCPPorts = [ 8000 ];
systemd.services.restic-prune = {
serviceConfig = {
Type = "oneshot";
User = "restic";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic \
--repo ${repository} \
--password-file ${config.age.secrets.resticKey.path} \
prune \
'';
};
systemd.timers.restic-prune = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-prune.service" ];
timerConfig.OnCalendar = [ "*-*-* 08:00:00" ];
};
systemd.services.restic-check = {
serviceConfig = {
Type = "oneshot";
User = "restic";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic \
--repo ${repository} \
--password-file ${config.age.secrets.resticKey.path} \
check \
'';
};
systemd.timers.restic-check = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-check.service" ];
timerConfig.OnCalendar = [ "*-*-* 07:00:00" ];
};
}

View File

@ -1,26 +0,0 @@
{ ... }:
let
whitelist = builtins.toFile "whitelist.txt" ''*'';
in
{
services.az-docker.enable = true;
virtualisation.oci-containers = {
backend = "docker";
containers."rss-bridge" = {
# https://hub.docker.com/r/rssbridge/rss-bridge/tags
image = "rssbridge/rss-bridge@sha256:7b8be6079488926287d7ba4043d24b679218ccb7bf87b4e47ff0571ec500c345";
autoStart = true;
ports = [
"8082:80"
];
volumes = [
"${whitelist}:/app/whitelist.txt"
"/etc/localtime:/etc/localtime:ro"
];
extraOptions = [
"--log-opt=tag='rss-brige'"
];
};
};
}

View File

@ -0,0 +1,58 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.az-nginx-fpm;
in
{
options = {
services.az-nginx-fpm = {
enable = lib.mkEnableOption "Enable Nginx with config for FPM in a container.";
dataDir = lib.mkOption {
type = lib.types.str;
description = "The directory where the application lives on the host.";
};
documentRoot = lib.mkOption {
type = lib.types.str;
description = "The directory where the FPM expects your code to be.";
default = "/var/www/html";
};
domain = lib.mkOption {
type = lib.types.str;
description = "The domain the service is being run from.";
};
port = lib.mkOption {
type = lib.types.number;
description = "The port FPM listens on.";
default = 9000;
};
};
};
config = lib.mkIf cfg.enable {
services = {
az-acme-base.enable = true;
nginx = {
appendHttpConfig = ''
index index.php;
'';
virtualHosts."${cfg.domain}" = {
enableACME = true;
forceSSL = true;
root = cfg.dataDir;
locations = {
"~ \\.php$" = {
extraConfig = ''
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME ${cfg.documentRoot}$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:${toString cfg.port};
'';
};
};
};
};
};
};
}

View File

@ -0,0 +1,41 @@
{ config, lib, ... }:
let
cfg = config.services.az-nginx-proxy;
in
{
options = {
services.az-nginx-proxy = {
enable = lib.mkEnableOption "Enable Nginx proxy, mainly to provide SSL.";
domain = lib.mkOption {
type = lib.types.str;
description = "The domain the service is being run from.";
};
port = lib.mkOption {
type = lib.types.number;
description = "The port FPM listens on.";
default = 8080;
};
};
};
config = lib.mkIf cfg.enable {
services = {
az-acme-base.enable = true;
nginx = {
appendHttpConfig = ''
# Disable embedding as a frame
add_header X-Frame-Options DENY;
'';
recommendedProxySettings = true;
virtualHosts."${cfg.domain}" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
proxyWebsockets = true; # needed if you need to use WebSocket
};
};
};
};
};
}

View File

@ -0,0 +1,55 @@
{ config, inputs, lib, ... }:
let
cfg = config.services.az-plex;
in
{
options = {
services.az-plex.enable = lib.mkEnableOption "Enable Plex running in Docker";
};
config = lib.mkIf cfg.enable {
age.secrets.plexClaim.file = "${inputs.self}/scrts/plex_claim.age";
networking = {
firewall.allowedTCPPorts = [
32400 # Web Interface/ Remote Access
];
firewall.allowedUDPPorts = [
1900 # DLNA
5353 # Bonjour/Avahi
32410 # GDM network discovery
32412 # GDM network discovery
32413 # GDM network discovery
32414 # GDM network discovery
32469 # Plex DLNA Server
];
};
services.az-docker.enable = true;
virtualisation.oci-containers = {
backend = "docker";
containers."plex" = {
autoStart = true;
# https://fleet.linuxserver.io/image?name=linuxserver/plex
image = "lscr.io/linuxserver/plex:1.32.1";
environment = {
TZ = " Europe/Zurich ";
PUID = "1000";
PGID = "1000";
VERSION = "docker";
};
environmentFiles = [ config.age.secrets.plexClaim.path ];
volumes = [
"/var/lib/plex/config:/config"
"/var/lib/plex/tmp:/transcode"
"/etc/localtime:/etc/localtime:ro"
];
extraOptions = [
''--mount=type=volume,source=media,target=/mnt/media,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/media,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
"--network=host"
"--log-opt=tag='plex'"
];
};
};
};
}

View File

@ -0,0 +1,18 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.az-postgresql;
in
{
options = {
services.az-postgresql.enable = lib.mkEnableOption "Enable PostgreSQL with settings for container clients.";
};
config = lib.mkIf cfg.enable {
services.postgresql = {
enable = true;
enableTCPIP = true;
settings.listen_addresses = pkgs.lib.mkForce "127.0.0.1,172.17.0.1";
};
networking.firewall.extraCommands = "iptables -A INPUT -p tcp --destination-port 5432 -s 172.16.0.0/12 -j ACCEPT";
};
}

View File

@ -84,7 +84,7 @@ in
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic \
--exclude-file=${inputs.self}/modules/restic-client/excludes.txt \
--exclude-file=${inputs.self}/modules/misc/restic-client/excludes.txt \
--tag home-dir \
backup /home/${config.az-username}

View File

@ -0,0 +1,79 @@
{ config, inputs, lib, pkgs, ... }:
let
cfg = config.services.az-restic-client-server-mysql;
in
{
options = {
services.az-restic-client-server-mysql = {
enable = lib.mkEnableOption "Enable restic backups for MariaDB.";
path = lib.mkOption {
type = lib.types.path;
description = "The directory to backup.";
};
tag = lib.mkOption {
type = lib.types.str;
description = "The tag to attach to the backups.";
default = "home-dir";
};
time = lib.mkOption {
type = lib.types.str;
description = "The time at which the backup runs.";
};
};
};
config = lib.mkIf cfg.enable {
services.az-telegram-notifications = {
enable = true;
};
age.secrets.resticKey.file = "${inputs.self}/scrts/restic.key.age";
systemd.timers."restic-backups" = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-backups.service" ];
timerConfig = {
OnCalendar = cfg.time;
};
};
systemd.services."restic-backups" = {
serviceConfig = {
User = "root";
Type = "oneshot";
};
environment = {
RESTIC_PASSWORD_FILE = config.age.secrets.resticKey.path;
RESTIC_REPOSITORY = "rest:http://10.7.89.30:8000";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic backup \
--exclude-file=${inputs.self}/modules/misc/restic-client/excludes.txt \
--tag ${cfg.tag} ${cfg.path}
${pkgs.mariadb}/bin/mariabackup --backup --user=root --stream=xbstream | \
${pkgs.restic}/bin/restic backup \
--tag mariadb \
--stdin \
--stdin-filename mariadb.xb
${pkgs.restic}/bin/restic forget \
--tag home-dir \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
${pkgs.restic}/bin/restic forget \
--tag mariadb \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
'';
};
};
}

View File

@ -0,0 +1,77 @@
{ config, inputs, lib, pkgs, ... }:
let
cfg = config.services.az-restic-client-server-postgres;
in
{
options = {
services.az-restic-client-server-postgres = {
enable = lib.mkEnableOption "Enable restic backups for PostgreSQL.";
path = lib.mkOption {
type = lib.types.path;
description = "The directory to backup.";
};
tag = lib.mkOption {
type = lib.types.str;
description = "The tag to attach to the backups.";
default = "home-dir";
};
time = lib.mkOption {
type = lib.types.str;
description = "The time at which the backup runs.";
};
};
};
config = lib.mkIf cfg.enable {
services.az-telegram-notifications.enable = true;
age.secrets.resticKey.file = "${inputs.self}/scrts/restic.key.age";
systemd.timers."restic-backups" = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-backups.service" ];
timerConfig = {
OnCalendar = cfg.time;
};
};
systemd.services."restic-backups" = {
serviceConfig = {
User = "root";
Type = "oneshot";
};
environment = {
RESTIC_PASSWORD_FILE = config.age.secrets.resticKey.path;
RESTIC_REPOSITORY = "rest:http://10.7.89.30:8000";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic backup \
--exclude-file=${inputs.self}/modules/misc/restic-client/excludes.txt \
--tag ${cfg.tag} ${cfg.path}
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dumpall | \
${pkgs.restic}/bin/restic backup \
--tag postgres \
--stdin \
--stdin-filename all_databases.sql
${pkgs.restic}/bin/restic forget \
--tag home-dir \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
${pkgs.restic}/bin/restic forget \
--tag postgres \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
'';
};
};
}

View File

@ -0,0 +1,62 @@
{ config, inputs, lib, pkgs, ... }:
let
cfg = config.services.az-restic-client-server;
in
{
options = {
services.az-restic-client-server = {
enable = lib.mkEnableOption "Enable restic backups on server systems.";
path = lib.mkOption {
type = lib.types.path;
description = "The directory to backup.";
};
tag = lib.mkOption {
type = lib.types.str;
description = "The tag to attach to the backups.";
default = "home-dir";
};
time = lib.mkOption {
type = lib.types.str;
description = "The time at which the backup runs.";
};
};
};
config = lib.mkIf cfg.enable {
services.az-telegram-notifications.enable = true;
age.secrets.resticKey.file = "${inputs.self}/scrts/restic.key.age";
systemd.timers."restic-backups" = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-backups.service" ];
timerConfig = {
OnCalendar = cfg.time;
};
};
systemd.services."restic-backups" = {
serviceConfig = {
User = "root";
Type = "oneshot";
};
environment = {
RESTIC_PASSWORD_FILE = config.age.secrets.resticKey.path;
RESTIC_REPOSITORY = "rest:http://10.7.89.30:8000";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic backup \
--exclude-file=${inputs.self}/modules/misc/restic-client/excludes.txt \
--tag ${cfg.tag} ${cfg.path}
${pkgs.restic}/bin/restic forget \
--tag home-dir \
--host ${config.networking.hostName} \
--keep-daily 7 \
--keep-weekly 5 \
--keep-monthly 12 \
--keep-yearly 75
'';
};
};
}

View File

@ -0,0 +1,82 @@
{ config, inputs, lib, pkgs, ... }:
let
cfg = config.services.az-restic-server;
in
{
options = {
services.az-restic-server = {
enable = lib.mkEnableOption "Enable a restic server.";
repository = lib.mkOption {
type = lib.types.path;
description = "The directory where your backups get stored.";
default = "/var/lib/restic-server";
};
};
};
config = lib.mkIf cfg.enable {
services.az-telegram-notifications.enable = true;
age.secrets.resticKey = {
file = "${inputs.self}/scrts/restic.key.age";
mode = "440";
owner = "restic";
group = "restic";
};
environment.systemPackages = with pkgs; [
restic
];
fileSystems."${cfg.repository}" = {
device = "10.7.89.108:restic-server";
fsType = "nfs";
options = [ "noatime" "hard" "nfsvers=4.0" ];
};
services.restic.server = {
enable = true;
dataDir = cfg.repository;
extraFlags = [ "--no-auth" ];
};
networking.firewall.allowedTCPPorts = [ 8000 ];
systemd.services.restic-prune = {
serviceConfig = {
Type = "oneshot";
User = "restic";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic \
--repo ${cfg.repository} \
--password-file ${config.age.secrets.resticKey.path} \
prune \
'';
};
systemd.timers.restic-prune = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-prune.service" ];
timerConfig.OnCalendar = [ "*-*-* 08:00:00" ];
};
systemd.services.restic-check = {
serviceConfig = {
Type = "oneshot";
User = "restic";
};
onFailure = [ "unit-status-telegram@%n.service" ];
script = ''
${pkgs.restic}/bin/restic \
--repo ${cfg.repository} \
--password-file ${config.age.secrets.resticKey.path} \
check \
'';
};
systemd.timers.restic-check = {
wantedBy = [ "timers.target" ];
partOf = [ "restic-check.service" ];
timerConfig.OnCalendar = [ "*-*-* 07:00:00" ];
};
};
}

View File

@ -0,0 +1,33 @@
{ config, lib, ... }:
let
cfg = config.services.az-rss-bridge;
whitelist = builtins.toFile "whitelist.txt" ''*'';
in
{
options = {
services.az-rss-bridge.enable = lib.mkEnableOption "Enable RSS bridge.";
};
config = lib.mkIf cfg.enable {
services.az-docker.enable = true;
virtualisation.oci-containers = {
backend = "docker";
containers."rss-bridge" = {
# https://hub.docker.com/r/rssbridge/rss-bridge/tags
image = "rssbridge/rss-bridge@sha256:7b8be6079488926287d7ba4043d24b679218ccb7bf87b4e47ff0571ec500c345";
autoStart = true;
ports = [
"8082:80"
];
volumes = [
"${whitelist}:/app/whitelist.txt"
"/etc/localtime:/etc/localtime:ro"
];
extraOptions = [
"--log-opt=tag='rss-brige'"
];
};
};
};
}

View File

@ -0,0 +1,123 @@
{ config, inputs, lib, ... }:
let
cfg = config.services.az-ttrss-postgres;
ttrssEnvironment = {
TZ = "Europe/Zurich";
TTRSS_DB_USER = "ttrss";
TTRSS_DB_NAME = "ttrssdb";
TTRSS_DB_HOST = "host.docker.internal";
TTRSS_SELF_URL_PATH = "https://${cfg.domain}/tt-rss";
TTRSS_SESSION_COOKIE_LIFETIME = "604800";
TTRSS_PLUGINS = "af_comics, af_readability, auth_internal, hotkeys_swap_jk, nginx_xaccel";
};
# https://github.com/Nebucatnetzer/tt-rss-aarch64/pkgs/container/tt-rss-aarch64%2Fttrss-fpm-pgsql-static/versions
ttrssImage = "ghcr.io/nebucatnetzer/tt-rss-aarch64/ttrss-fpm-pgsql-static@sha256:4842ca145ad3d57b1b627fdf9ea4349aeeda9e31134deee1e6a64694f6825754";
ttrssService = "${config.virtualisation.oci-containers.backend}-ttrss";
in
{
options = {
services.az-ttrss-postgres = {
enable = lib.mkEnableOption "Enable TTRSS";
domain = lib.mkOption {
type = lib.types.str;
description = "The domain TTRSS is being run from.";
};
};
};
config = lib.mkIf cfg.enable {
age.secrets.ttrssEnv.file = "${inputs.self}/scrts/ttrss_env.age";
services = {
az-docker.enable = true;
az-nginx-fpm = {
enable = true;
dataDir = "/var/lib/ttrss/html";
domain = cfg.domain;
};
az-postgresql.enable = true;
nginx.virtualHosts."${cfg.domain}".locations = {
"/".extraConfig = ''
try_files $uri $uri/ = 404;
'';
"/tt-rss/cache".extraConfig = ''
aio threads;
internal;
'';
"/tt-rss/backups".extraConfig = ''
internal;
'';
};
postgresql = {
authentication = "host ttrssdb ttrss 172.16.0.0/12 scram-sha-256";
ensureDatabases = [ "ttrssdb" ];
ensureUsers = [{
name = "ttrss";
ensurePermissions = {
"DATABASE ttrssdb " = "ALL PRIVILEGES";
};
}];
};
};
virtualisation.oci-containers = {
backend = "docker";
containers."ttrss" = {
image = ttrssImage;
autoStart = true;
environment = ttrssEnvironment;
environmentFiles = [ config.age.secrets.ttrssEnv.path ];
ports = [
"9000:9000"
];
volumes = [
"/var/lib/ttrss/html:/var/www/html"
"/etc/localtime:/etc/localtime:ro"
];
extraOptions = [
"--add-host=host.docker.internal:host-gateway"
"--log-opt=tag='ttrss'"
];
};
containers."backup" = {
image = ttrssImage;
autoStart = true;
environment = ttrssEnvironment;
environmentFiles = [ config.age.secrets.ttrssEnv.path ];
volumes = [
"/var/lib/ttrss/html:/var/www/html"
"/var/lib/ttrss/backup:/backup"
"/etc/localtime:/etc/localtime:ro"
];
cmd = [ "/opt/tt-rss/dcron.sh" "-f" ];
extraOptions = [
"--add-host=host.docker.internal:host-gateway"
"--log-opt=tag='ttrss-backup'"
];
};
containers."updater" = {
image = ttrssImage;
autoStart = true;
environment = ttrssEnvironment;
environmentFiles = [ config.age.secrets.ttrssEnv.path ];
volumes = [
"/var/lib/ttrss/html:/var/www/html"
"/etc/localtime:/etc/localtime:ro"
];
cmd = [ "/opt/tt-rss/updater.sh" ];
dependsOn = [ "ttrss" ];
extraOptions = [
"--add-host=host.docker.internal:host-gateway"
"--log-opt=tag='ttrss-updater'"
];
};
};
systemd.services.${ttrssService}.after = [ "nginx.service" ];
systemd.services.postgresql.after = [ "${ttrssService}.service" ];
};
}

View File

@ -1,109 +0,0 @@
{ domain }: { config, inputs, ... }:
let
ttrssEnvironment = {
TZ = "Europe/Zurich";
TTRSS_DB_USER = "ttrss";
TTRSS_DB_NAME = "ttrssdb";
TTRSS_DB_HOST = "host.docker.internal";
TTRSS_SELF_URL_PATH = "https://${domain}/tt-rss";
TTRSS_SESSION_COOKIE_LIFETIME = "604800";
TTRSS_PLUGINS = "af_comics, af_readability, auth_internal, hotkeys_swap_jk, nginx_xaccel";
};
# https://github.com/Nebucatnetzer/tt-rss-aarch64/pkgs/container/tt-rss-aarch64%2Fttrss-fpm-pgsql-static/versions
ttrssImage = "ghcr.io/nebucatnetzer/tt-rss-aarch64/ttrss-fpm-pgsql-static@sha256:4842ca145ad3d57b1b627fdf9ea4349aeeda9e31134deee1e6a64694f6825754";
ttrssService = "${config.virtualisation.oci-containers.backend}-ttrss";
in
{
imports = [
(import "${inputs.self}/modules/nginx-fpm" {
dataDir = "/var/lib/ttrss/html";
inherit domain;
})
"${inputs.self}/modules/postgresql"
];
age.secrets.ttrssEnv.file = "${inputs.self}/scrts/ttrss_env.age";
services.postgresql = {
authentication = "host ttrssdb ttrss 172.16.0.0/12 scram-sha-256";
ensureDatabases = [ "ttrssdb" ];
ensureUsers = [{
name = "ttrss";
ensurePermissions = {
"DATABASE ttrssdb " = "ALL PRIVILEGES";
};
}];
};
services.az-docker.enable = true;
virtualisation.oci-containers = {
backend = "docker";
containers."ttrss" = {
image = ttrssImage;
autoStart = true;
environment = ttrssEnvironment;
environmentFiles = [ config.age.secrets.ttrssEnv.path ];
ports = [
"9000:9000"
];
volumes = [
"/var/lib/ttrss/html:/var/www/html"
"/etc/localtime:/etc/localtime:ro"
];
extraOptions = [
"--add-host=host.docker.internal:host-gateway"
"--log-opt=tag='ttrss'"
];
};
containers."backup" = {
image = ttrssImage;
autoStart = true;
environment = ttrssEnvironment;
environmentFiles = [ config.age.secrets.ttrssEnv.path ];
volumes = [
"/var/lib/ttrss/html:/var/www/html"
"/var/lib/ttrss/backup:/backup"
"/etc/localtime:/etc/localtime:ro"
];
cmd = [ "/opt/tt-rss/dcron.sh" "-f" ];
extraOptions = [
"--add-host=host.docker.internal:host-gateway"
"--log-opt=tag='ttrss-backup'"
];
};
containers."updater" = {
image = ttrssImage;
autoStart = true;
environment = ttrssEnvironment;
environmentFiles = [ config.age.secrets.ttrssEnv.path ];
volumes = [
"/var/lib/ttrss/html:/var/www/html"
"/etc/localtime:/etc/localtime:ro"
];
cmd = [ "/opt/tt-rss/updater.sh" ];
dependsOn = [ "ttrss" ];
extraOptions = [
"--add-host=host.docker.internal:host-gateway"
"--log-opt=tag='ttrss-updater'"
];
};
};
services.nginx.virtualHosts."${domain}".locations = {
"/".extraConfig = ''
try_files $uri $uri/ = 404;
'';
"/tt-rss/cache".extraConfig = ''
aio threads;
internal;
'';
"/tt-rss/backups".extraConfig = ''
internal;
'';
};
systemd.services.${ttrssService}.after = [ "nginx.service" ];
systemd.services.postgresql.after = [ "${ttrssService}.service" ];
}

View File

@ -8,18 +8,20 @@ in
ip = "10.7.89.109";
inherit hostname;
})
(import "${inputs.self}/modules/restic-client-server-mysql" {
path = "/home/andreas";
time = "00:30";
})
(import "${inputs.self}/modules/nginx-proxy" {
inherit domain;
})
];
services = {
az-gitea = {
enable = true;
domain = domain;
};
az-nginx-proxy = {
enable = true;
domain = domain;
};
az-restic-client-server-mysql = {
enable = true;
path = "/home/andreas";
time = "00:30";
};
};
}

View File

@ -5,16 +5,18 @@
ip = "10.7.89.123";
inherit hostname;
})
(import "${inputs.self}/modules/restic-client-server" {
path = "/home/andreas";
time = "01:00";
})
(import "${inputs.self}/modules/nginx-proxy" {
domain = "mail.zweili.org";
})
];
services = {
az-mailserver.enable = true;
az-nginx-proxy = {
enable = true;
domain = "mail.zweili.org";
};
az-restic-client-server = {
enable = true;
path = "/home/andreas";
time = "01:00";
};
};
}

View File

@ -5,11 +5,6 @@
ip = "10.7.89.150";
inherit hostname;
})
(import "${inputs.self}/modules/restic-client-server" {
path = "/home/andreas";
tag = "management";
time = "23:30";
})
];
fileSystems = {
"/mnt/external" = {
@ -25,6 +20,12 @@
az-docker.enable = true;
az-logs-share.enable = true;
az-rclone-webdav.enable = true;
az-restic-client-server = {
enable = true;
path = "/home/andreas";
tag = "management";
time = "23:30";
};
};
# Enable dictionaries
programs = {

View File

@ -5,10 +5,6 @@
ip = "10.7.89.103";
inherit hostname;
})
(import "${inputs.self}/modules/restic-client-server-mysql" {
path = "/home/andreas";
time = "01:30";
})
];
services = {
@ -16,5 +12,10 @@
enable = true;
domain = "nextcloud.2li.ch";
};
az-restic-client-server-mysql = {
enable = true;
path = "/home/andreas";
time = "01:30";
};
};
}

View File

@ -5,14 +5,15 @@
ip = "10.7.89.112";
inherit hostname;
})
(import "${inputs.self}/modules/restic-client-server" {
path = "/var/lib/plex";
tag = "plex";
time = "02:30";
})
"${inputs.self}/modules/plex"
];
services = {
az-media-share.enable = true;
az-plex.enable = true;
az-restic-client-server = {
enable = true;
path = "/var/lib/plex";
tag = "plex";
time = "02:30";
};
};
}

View File

@ -5,10 +5,6 @@
ip = "10.7.89.99";
inherit hostname;
})
(import "${inputs.self}/modules/restic-client-server" {
path = "/home/andreas";
time = "00:00";
})
];
services = {
@ -16,6 +12,11 @@
az-grav.enable = true;
az-haproxy.enable = true;
az-heimdall.enable = true;
az-restic-client-server = {
enable = true;
path = "/home/andreas";
time = "00:00";
};
nginx = {
commonHttpConfig = ''
# Add HSTS header with preloading to HTTPS requests.

View File

@ -5,6 +5,8 @@
ip = "10.7.89.30";
inherit hostname;
})
"${inputs.self}/modules/restic-server"
];
services = {
az-restic-server.enable = true;
};
}

View File

@ -8,16 +8,23 @@ in
ip = "10.7.89.115";
inherit hostname;
})
(import "${inputs.self}/modules/nginx-proxy" {
];
services = {
az-nginx-proxy = {
enable = true;
domain = "rss-bridge.2li.ch";
port = "8082";
})
(import "${inputs.self}/modules/restic-client-server-postgres" {
port = 8082;
};
az-restic-client-server-postgres = {
enable = true;
path = "/var/lib/ttrss";
tag = "tt-rss";
time = "23:00";
})
"${inputs.self}/modules/rss-bridge"
(import "${inputs.self}/modules/ttrss-postgres" { inherit domain; })
];
};
az-rss-bridge.enable = true;
az-ttrss-postgres = {
enable = true;
domain = domain;
};
};
}