reduce, reuse, refine (#3)

* reduce, reuse, refine

* more refining and replacing

* More refining

* Removing unused code such as homepage and traefik

* Remove homepage references.
This commit is contained in:
Joseph Hanson 2024-05-19 06:39:08 -05:00 committed by GitHub
parent d1ac19d946
commit 6a278729f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
102 changed files with 188 additions and 5831 deletions

21
LICENSE
View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 Truxnell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -2,6 +2,10 @@
[Repository Documentation](https://truxnell.github.io/nix-config/)
## Thank you Truxnell
Thank you for a lot of the groundwork you laid for the base nixos configuration and a lot of modules!
## Getting started
To Install

View file

@ -73,7 +73,6 @@
"aarch64-linux"
"x86_64-linux"
];
in
rec {
# Use nixpkgs-fmt for 'nix fmt'
@ -91,11 +90,8 @@
);
nixosConfigurations =
with self.lib;
let
specialArgs = {
inherit inputs outputs;
};
# Import overlays for building nixosconfig with them.
overlays = import ./nixos/overlays { inherit inputs; };
@ -145,9 +141,10 @@
};
in
rec {
{
"durincore" = mkNixosConfig {
# NixOS laptop - T470 Thinkpad
# T470 Thinkpad
# Nix dev laptop
hostname = "durincore";
system = "x86_64-linux";
hardwareModules = [
@ -162,7 +159,7 @@
};
"varda" = mkNixosConfig {
# Arm64 cax21 @ Hetzner
# forgejo server
hostname = "varda";
system = "aarch64-linux";
hardwareModules = [
@ -186,5 +183,4 @@
in
nixtop;
};
}

View file

@ -1,8 +0,0 @@
---
# Config for garnix.io builds & caching
builds:
include:
- homeConfigurations.*
- nixosConfigurations.*
- packages.x86_64-linux.*
- packages.aarch64-linux.*

View file

@ -1,95 +0,0 @@
site_name: Truxnell's NixOS homelab
site_author: truxnell
site_url: https://truxnell.github.io/nix-config/
# Repository
repo_name: truxnell/nix-config
repo_url: https://github.com/truxnell/nix-config
docs_dir: ./docs
site_dir: ./site
copyright: Copyright © 2024 Nat Allan
theme:
name: material
# custom_dir: ../../docs/overrides
features:
- announce.dismiss
- content.code.annotate
- content.code.copy
- navigation.expand
- navigation.indexes
- navigation.path
# - navigation.sections
- navigation.footer
# - navigation.tabs
- navigation.top
- search.suggest
palette:
- scheme: slate
media: "(prefers-color-scheme: light)"
primary: black
accent: indigo
toggle:
icon: material/brightness-4
name: Switch to light mode
- scheme: default
media: "(prefers-color-scheme: dark)"
toggle:
icon: material/brightness-7
name: Switch to dark mode
font:
text: Roboto
code: Roboto Mono
icon:
logo: simple/nixos
annotations: material/chat-question
# Plugins
plugins:
- search:
separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
- minify:
minify_html: true
# Extensions
markdown_extensions:
- admonition
- abbr
- attr_list
- md_in_html
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.caret
- pymdownx.tilde
- pymdownx.snippets:
check_paths: true
auto_append:
- ./docs/includes/abbreviations.md
- pymdownx.superfences
- toc:
permalink: true
toc_depth: 3
nav:
- readme.md: index.md
- Overview:
- Goals: overview/goals.md
- Features: overview/features.md
- Design Principals: overview/design.md
- Structure: overview/structure.md
- Maintenance:
- Software Updates: maintenance/software_updates.md
- Backups: maintenance/backups.md
- Monitoring:
- SystemD failures: monitoring/systemd.md
- Nix Warnings: monitoring/warnings.md
- Other Features:
- MOTD: motd.md

View file

@ -4,29 +4,14 @@ with lib;
rec {
firstOrDefault = first: default: if first != null then first else default;
existsOrDefault = x: set: default: if builtins.hasAttr x set then builtins.getAttr x set else default;
# Will be v. useful when i grok
# https://github.com/ahbk/my-nixos/blob/5fe1521b11422c66fd823b442393b3b044a5a5b8/nix#L5
# pick a list of attributes from an attrSet
# mySystem.pick = attrNames: attrSet: filterAttrs (name: value: elem name attrNames) attrSet;
# create an env-file (package) that can be sourced to set environment variables
# mySystem.mkEnv = name: value: pkgs.writeText "${name}-env" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") value));
# loop over an attrSet and merge the attrSets returned from f into one (latter override the former in case of conflict)
# mySystem.mergeAttrs = f: attrs: builtins.foldlAttrs (acc: name: value: (recursiveUpdate acc (f name value))) { } attrs;
# main service builder
mkService = options: (
let
user = existsOrDefault "user" options "568";
group = existsOrDefault "group" options "568";
addTraefikLabels = if (builtins.hasAttr "container" options) && (builtins.hasAttr "addTraefikLabels" options.container) then options.container.addTraefikLabels else true;
addToHomepage = lib.attrsets.attrByPath [ "homepage" "enable" ] true options;
homepageIcon = if (builtins.hasAttr "homepage" options) && (builtins.hasAttr "icon" options.homepage) then options.homepage.icon else "${options.app}.svg";
subdomain = existsOrDefault "subdomainOverride" options options.app;
host = existsOrDefault "host" options "${subdomain}.${options.domain}";
@ -41,9 +26,7 @@ rec {
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "tmpfs" ] false options) [ (map (folders: "--tmpfs=${folders}") tmpfsFolders) ]
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "noNewPrivileges" ] false options) [ "--security-opt=no-new-privileges" ]
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "dropAll" ] false options) [ "--cap-drop=ALL" ]
;
in
{
virtualisation.oci-containers.containers.${options.app} = mkIf options.container.enable {
@ -53,68 +36,13 @@ rec {
TZ = options.timeZone;
} // options.container.env;
environmentFiles = lib.attrsets.attrByPath [ "container" "envFiles" ] [ ] options;
volumes = [ "/etc/localtime:/etc/localtime:ro" ]
++ lib.optionals (lib.attrsets.hasAttrByPath [ "container" "persistentFolderMount" ] options) [
volumes = [ "/etc/localtime:/etc/localtime:ro" ] ++
lib.optionals (lib.attrsets.hasAttrByPath [ "container" "persistentFolderMount" ] options) [
"${options.persistence.folder}:${options.container.persistentFolderMount}:rw"
]
++ lib.attrsets.attrByPath [ "container" "volumes" ] [ ] options;
labels = mkIf addTraefikLabels (mkTraefikLabels {
name = subdomain;
inherit (options) port;
inherit (options) domain;
url = host;
});
] ++ lib.attrsets.attrByPath [ "container" "volumes" ] [ ] options;
extraOptions = containerExtraOptions;
};
systemd.tmpfiles.rules = lib.optionals (lib.attrsets.hasAttrByPath [ "persistence" "folder" ] options) [ "d ${options.persistence.folder} 0750 ${user} ${group} -" ]
;
# built a entry for homepage
mySystem.services.homepage.${options.homepage.category} = mkIf addToHomepage [
{
${options.app} = {
icon = homepageIcon;
href = "https://${ host }";
inherit host;
inherit (options) description;
};
}
];
}
);
# build up traefik docker labels
mkTraefikLabels = options: (
let
inherit (options) name;
subdomain = if builtins.hasAttr "subdomain" options then options.subdomain else options.name;
host = existsOrDefault "host" options "${options.name}.${options.domain}";
# created if port is specified
service = if builtins.hasAttr "service" options then options.service else options.name;
middleware = if builtins.hasAttr "middleware" options then options.middleware else "local-ip-only@file";
in
{
"traefik.enable" = "true";
"traefik.http.routers.${name}.rule" = "Host(`${host}`)";
"traefik.http.routers.${name}.entrypoints" = "websecure";
"traefik.http.routers.${name}.middlewares" = "${middleware}";
} // attrsets.optionalAttrs (builtins.hasAttr "port" options) {
"traefik.http.routers.${name}.service" = service;
"traefik.http.services.${service}.loadbalancer.server.port" = "${builtins.toString options.port}";
} // attrsets.optionalAttrs (builtins.hasAttr "scheme" options) {
"traefik.http.routers.${name}.service" = service;
"traefik.http.services.${service}.loadbalancer.server.scheme" = "${options.scheme}";
} // attrsets.optionalAttrs (builtins.hasAttr "service" options) {
"traefik.http.routers.${name}.service" = service;
systemd.tmpfiles.rules = lib.optionals (lib.attrsets.hasAttrByPath [ "persistence" "folder" ] options) [ "d ${options.persistence.folder} 0750 ${user} ${group} -" ];
}
);
}

View file

@ -1,5 +1,3 @@
{
mySystem = import ./nixos;
}

View file

@ -1,9 +0,0 @@
{
imports = [
./sonarr
./radarr
./lidarr
./readarr
./prowlarr
];
}

View file

@ -1,108 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "lidarr";
image = "ghcr.io/onedr0p/lidarr:2.2.5";
user = "568"; #string
group = "568"; #string
port = 8686; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
sops.secrets."services/${app}/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = config.users.users.kah.name;
inherit (config.users.users.kah) group;
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
dependsOn = [ "prowlarr" ];
environment = {
PUSHOVER_DEBUG = "false";
PUSHOVER_APP_URL = "${app}.${config.mySystem.domain}";
LIDARR__INSTANCE_NAME = "Lidarr";
LIDARR__APPLICATION_URL = "https://${app}.${config.mySystem.domain}";
LIDARR__LOG_LEVEL = "info";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Lidarr = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Music management";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_LIDARR__API_KEY}}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app;
user = builtins.toString user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
lidarr:
env: ENC[AES256_GCM,data:O4d3rRXSIEngArtNd+faqg==,iv:uZjQYc+eWtyHSDiWy2ApR4Hhly1vKV2cl50mWxNImhk=,tag:q6C5iyT5GJAgmi2Ei0dL/A==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxQnV5QXg0YXpKK3JZdXFL
dVRBbjVGRkl1VWhzQzVUT0pOMU92OHI1NUNvClgwaUhpSVJzbENjY0MzN0tXUDdl
ZnpLa0dsL2d1cDh2MmIrL0ZXK0dlWWcKLS0tIEJYNStPRWpFTmhWWHlVRDJnOEhT
Sm9kK04zOHVlS3diNzlRMEk1VW5VcncKVMW00zzIjYeGkMaHI5qGzVVsrQMzXxmt
d4QS4OVt+LSiZVFkp7o84Lwzg42ljxG8TYGFZrXItzlfA8H+1Mo84w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvbkpVVkVmNnJiWTV6Mm4r
OW1HQ3hBZVAwOGxrSDJNVUpUTWtCblhQQmo0CldBWGNzblUvVGptNVRtR2ZCSkly
L0cvdUZ6Tm1KcmJ4MFdNT05iQzVrOXMKLS0tIEY0cmRhSkY0L0V2dzhvaEFwYzQ3
M3g0MGVKUWlORlZxMlo4U0N2OEJJQkEK5nIb7vaPxO2hfKRD2pes/zC5rVDrcL1l
fah/WWuh1UcLZWloj6Vqx+xPm16G10wzDJEWD/ANGTly3ke3aD2tgg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwMDRPZjc5OWJvczBmbFoy
WnQ0VVA1ZThVdm44NnhrV2dNWUtaQ0E1SlVzCjR4TnNRVDdXWFdqMktMUHcwQlJn
RnYzZndYQ1paVkJWTUw3R3VLR1VtSVEKLS0tIG10RmNrcGovcWNCOG53aEZLR2U0
UVR6L3ovamh2Rm1uTXJVUlZoV0xuWUUKQkF1Ss94AkIBh3y/tSGuHe1VOPO49tHK
Lh42/KE+8Jsev1hZfKzhq+6J3yi5+aIrjuFWYhJEfu1SM29J9CNZMA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrK08xbkUyY1dSend4NDd0
UjkrNW81a0NGUjVFS3NQc2V1UUpOczFqZkNnCno1Nkdyb1AvT1dhN3pySVZXeE1W
Q2ZYeUFsZmxScmtETHJnUkNyTGt3Q0kKLS0tIHBjV0JCYkxraTFDckVxemRpbTZM
SmJ1U1U5RStxcmR5a2VJV1pQNUx1MHMK1GuvIoo4XQZmLOvh2lluzn49h7My7/XW
tCtQEz0w0jAVA2R+QBi+IfAL3ZlHmRIBEOfL8OWmewnIDyOSrmOWuQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:oRC7wCHbR7j6EM37aNu/HUxWECNjU5WUdgtBnKa15LnUDH5RmqzUdmLcqE7rWSxjhVdAG5KdukeUilic/EF3+Z36cClENaEX5MYDbr85DAv9Fh5eb7vVuqnxyCf1H4LLeDFxR7OS+i5bWL8yR0xmCrzQeq8H5PSZDtKDyymE7tc=,iv:uQBQi8J5hIk9uKo1+wuioFeRwKbKm4CZ1k8oz/NvMpA=,tag:D5OSyWS1bLHTij587aUxjA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,105 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "prowlarr";
image = "ghcr.io/onedr0p/prowlarr:1.16.2.4435@sha256:3d3d5702d40824da9ece02f465dbf221dfa726846e9212bc3fe89af5562e6e9e";
user = "568"; #string
group = "568"; #string
port = 9696; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
sops.secrets."services/${app}/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = config.users.users.kah.name;
inherit (config.users.users.kah) group;
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
environment = {
PUSHOVER_DEBUG = "false";
PUSHOVER_APP_URL = "${app}.${config.mySystem.domain}";
PROWLARR__INSTANCE_NAME = "Prowlarr";
PROWLARR__APPLICATION_URL = "https://${app}.${config.mySystem.domain}";
PROWLARR__LOG_LEVEL = "info";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
volumes = [
"${appFolder}:/config:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Prowlarr = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Content locator";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_PROWLARR__API_KEY}}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
prowlarr:
env: ENC[AES256_GCM,data:RfSMBc1GuRAnMi2IwCp1yA==,iv:Qwixp/vl+fwV6u5Mrz49CvlTqm175ir501TMNb8DAiU=,tag:vWmDAJIx+xgf1JZXsgvZAg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOSjMxdWdxTHlWbGJkNVFi
a2llUzhZTjk1aTRQeGZWUGVDRlp2MGRRYm13CjZKdGJwby9SQlRhRUNRTUE5OVU4
UHRtVWhldzBudzVoT3VDaXZZSk8xVTAKLS0tIFhZcnhweC9RbWphYVpWRWsvd1FM
ejlOUjFFb1djVkZPRFg5V2RRUjlVYk0KS6hkIaUrA87JZFy17GQCHGwOPP/I5FOt
e/3HWlon+q8S97gAKjK/B723YpeQII9IJOFnnzpf/9iYbfCRCt5PGg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZR3g2bXI2alA0bGVscjBr
cWVHVE5PT01NQWk4cktTc01SeFdhekIvTWt3CkFzcjBsMGZJR0p3cWdQSlpqTUtF
MnAvQlc3NE1xN0hyTHZkL3FWRkZVMUUKLS0tIFFEQ01ndTV4L0E4aWI3MmtycGJC
bFYzaG1ybnBSZ0VCRnNxWHJPckhiOGMKY6pWJ3Y+HC0rPVWU1Jev6LyGe8XWl//N
ExvlsfXWAIrFPPhuxrrX58vvupiQnC39NOvlDAaK2MhgfAqK0Prx3A==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2U29taVkzWmVqbDY0RWJX
alZ6ODdPd0NXMHBnRW80UHNYcXN5eEd1S0JZCkg0akM0WGhiRzRhNFRIWERqaENN
V0VTV3VRT1ZkR25UbFdMdFdwS2NWbE0KLS0tIE9nT2lrZzRYb3krK0tMWmt4ajNS
OTBWUEEwRzR6c2tKUlNEQkFrSDc1eG8KBvg21rH2DBdsKu3yPlpcG3qPrTARLqKv
s7j3wf69rMOeCDRr8axHvAQBaILRQXfsMvcg958hHuxkxgmXyvmsnw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFbVpQQURsQlNHNWtqMEMv
MnhsMndzTkduaXBMblNxa1Bpb2dPT21OTFdrCitBdkE2OHBWS1VyU0pTQVU4Y2cx
Y01mTCtUdExmT0JmbnNrZEpaZXMraWsKLS0tIDBZVmhzc29WVVJsQm5hSTVLYllF
NitGTFJqM0lTYkJoRzRwaEpIL2hHYjgKk3PPKX1oSS7vXOykj8YSCM0Mqmvs/56k
BvcqOi2UymCWAdWd4doKiTGOCnPbvPbcVn/DCP7IiJ7tGovW3Hds3w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:sbFacPQYDCUu8tqBhvNRl22IlgycS5I1NLPrdQ2mI7MBqbDjvUMdfNL/sdHTnnPEWbYmPxdm1eymyRE4Bi+RKAYYtj400Rv7oZtXcivXdodTFW1WnxvPs4vaW5eLPuoKY8fbkPJBN0dk5g/rTNsIgbDYGU20VQh4au3pdIP/1Ds=,iv:RL1747DNQX/p1X0IDnVfdtuBDovD7M3vYdPcWwZ4e3Q=,tag:5aLv5VZSYwFeUx8X6IKb1Q==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,110 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "radarr";
image = "ghcr.io/onedr0p/radarr:5.4.6.8723@sha256:3198f09197697a4d57f995650ebf34b57b2fdbb991dac1611ad8356d9e8bda8e";
user = "568"; #string
group = "568"; #string
port = 7878; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
sops.secrets."services/${app}/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = config.users.users.kah.name;
inherit (config.users.users.kah) group;
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
dependsOn = [ "prowlarr" ];
environment = {
PUSHOVER_DEBUG = "false";
PUSHOVER_APP_URL = "${app}.${config.mySystem.domain}";
RADARR__INSTANCE_NAME = "Radarr";
RADARR__APPLICATION_URL = "https://${app}.${config.mySystem.domain}";
RADARR__LOG_LEVEL = "info";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Radarr = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Movie management";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_RADARR__API_KEY}}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
radarr:
env: ENC[AES256_GCM,data:g2nOfHP6L3XzAXov85ObnA==,iv:wQuUoMQTSK0LhqITzwfT9jzar0AgDd/XjaGZqNULEKA=,tag:P575LQESgmqcK+lt6qjnLw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVE9jMWhqNDZkMVVyM0w3
ck9vcVYwak5oeTJBd1ZhbENHb2laWmZqalZjClVGSXl6Uk1wK2N3UGJ6SzZ3OU9N
NGoweU5IUzc1M3RocGtJbWkxWkorbmsKLS0tIEVlandoSmovWGNPeUU0SkQ4RXpX
a2hDQzZ5NWd0eGExSVBCV1llZ0ROZTAKc11CpTzPGUjnvszlbup4C2/tiFDAcg8X
3MPCJyx7AZpEVXaU4XXGjx5AGuNsNq/AK0t5Erl2IV9onr+2R5oWYA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKNTJOYzZON2dpRzFLUnFN
TDlReHhuOW1rWjZDUjEzZ0R4WjRYazRNQjBNCkU3SEZqa09mUk9ZZWpBbUxJdnov
QzA5a3BOSDZNSGNOZmhkaWxBck9PWkEKLS0tIFNsUzBRZndxUVdPMklHanJRUjNJ
UTVxK2JJQ29xa2V0ZURDSGcvdUQ0TzAKxED8XhpsizFpEAryqoFDcpCyFeLB9o9H
nhL2KgyYwO5dE4EblcEH6TQ05tn4Z5hauytKtD3ScisOAtUuSYTXTQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6YnMzVGdNb2dzcEY5YWF1
MHVrZ01mNlo1em9zanh1OXhjdUJpUExJWWg0CnNDQXFmVlJoenpmQmxnM1pmbUc1
VlRYcWx0SzkrR1hMdGF0T2dxeUtaQkkKLS0tIENpZ2E4N01YRTgwRVRiL0lNT3pv
a0ZVeHd2VjNSdmN6Wk9iOHVEYzhZSWsKWIX7et7d34D5sFHIXORJBBtV0NlGIAey
BKsLefbu4HA20FE29MbN9FgUEFhWWMmUbGdfTqZ1tLeIkxfnUTwaiw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBTmRGUktWYmZlRjhrbmpa
dGFnRDRiNFJSeUw2a0VWQktNTFJPRDNYclI4CkVmZkJlYVVlRDkvSzkvcnlYZC9a
Nm00aEZlRmRnQ3lOOEtvZUNaU3hjU1kKLS0tIEdHQmQrbHQvNExCMExlOE1Bc0Jk
TzNUUHplZXhCVWpVSmp1MjJUK2VFbmMKst2kIb/iDFtkSTOachOMtf7EQQXgbuq9
OvUjBi7pGQZyR3R2Xd53TyuB/XN/oP87HBO9J5sJaL7JM/E2GiMMDQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:ZqR5/KDorn+Aa729BpNkQuUuSTm5KRlJ+IW/78W2TvURhC/9E2GjjPSXe3+xUhDQ/dx1L/OImjkqehfpnRcuIkrYzMyUg6m7Vi5dbRms6q6vrxmyH673JMuRL0SCtCEvk5cGPZP8Gpy1iVyolLFa/e85/d9/QddFPm2ol+PIfF4=,iv:ciZtUoUrehvqd1YktiMJ0kxloPZXlLeFopHGG2O7xwg=,tag:z/n0By181i9pacikNM3CIQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,106 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "readarr";
image = "ghcr.io/onedr0p/readarr-nightly:0.3.25.2515";
user = "568"; #string
group = "568"; #string
port = 8787; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
sops.secrets."services/${app}/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = config.users.users.kah.name;
inherit (config.users.users.kah) group;
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
dependsOn = [ "prowlarr" ];
environment = {
TZ = "${config.time.timeZone}";
READARR__INSTANCE_NAME = "Lidarr";
READARR__APPLICATION_URL = "https://${app}.${config.mySystem.domain}";
READARR__LOG_LEVEL = "info";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Readar = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Book management";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_READARR__API_KEY}}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
readarr:
env: ENC[AES256_GCM,data:qeJ2QSYl4QwJdZY9EwUyxw==,iv:juUUsv+tm9+2fRjXuQKToq4leb8SwoMlD/XSzwK4tds=,tag:ATdu3cvUe5xnSDQrSjJpEg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2TG9jcEQvTkRRVlV2NFBm
cGtqcnljeUVBN3R5djN5cktKN1pjTGZkbkRRCjlnb1lsWTIwZFJockxNVThFcG1Z
bGxRODBEODdiWDhoNjJGejJGbG5wL0EKLS0tICsrMVVpWVVWOWRGd0l3TVJ3WGJL
eVpiZGtvZlhLdW1nNTVZZHl4aDZpdm8KeMcKEiI57FIl6cMz4A7OiiEMx+4A3JHD
FOONn+HkF9EXUWTxNyfczDjP/5av8xgVnB4dxItvI1edeZKebthIRA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwcGRCajhLWUp1SnhmbHVG
TUVzUkFHQTV6ZURVZ0lxWjRSTHJETEtEd2xrCkQ5LzFNbVptNXErVDdpQWNRSk8y
RC9yenkzUmlKRExUMWVIRGpKV1c1aDgKLS0tIDByOFBkVkxGYWMvUnVMb1Z3YmVl
elhxUkJkUkptbTY0K1NuQjZaZjRlLzgKZqQUyR4iiRbWrLGabJnQotIxorXpmuGc
2SxWtWGHwJzlzkPy1C7D/mLwfzcNwicZnNSKPGcKv6krhrZnlrBR2g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDQ1c2ejNYd1NNZTBlMWNV
WHIraHFPSU8rWVZuUHV6ZWp2Z2h1dDRnckhJCmpybVRyUHl3S0IvUnBveUc0VUVG
T1BaTnJTZlkyYWRLYXczMFgxeEdSeFUKLS0tIG9WTWpUZWtWUWVXLzFxMndiSVFN
QTJCK3llaFVYN3JDdDBGZ2RNNlVtN2cKL3nx9qLMBVYFRdIv3s09a7b0m2vnL+JA
flKp/BhauIBNXMiG5YlFyjkpTuADY7GyCxJBOUere2fVVRKLXKPQpA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUdm40TnJpSmFkRWcvUXRa
bmdFSmYzd2MzellUTFIzVEdOYnlNZVdicENjCjBZcENtY094MXc2MVdWcnNWV1hn
QmhnL2QyczkzazkrZU9TZDBXMEpoNlEKLS0tIHVaWFFPYi80YXlSWU9SN3RHR0xm
UnZvc3hmcXBXTUk2VFozRkpWQjFvWTgKaBNOARVfCmBg9avayVWNmuN42N2oas1c
ViaEfbzNi50jJiSjebcdfVb8GZSPi5laaGPlcBlTaH4/tIVSO0v6oQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:U2RcBHHHyDY0KFGr8XMmiMtpVv8WsfaMmKPasJvh8SR56njkGFoH0CvYr3tbGfOy0P4TWddh4ywlFkCA0LkWEv6Uh/0jxgq1ZYiKvq5Vrv0wyT5xP6kC5cBtST7+y14NrMbAiT4hO+sfw9utH/b/C0YHmUl6WLJaYbikJFQmx4c=,iv:QbKtME9p2i+/E51pntOjRwtSEgz4iq4gi81dCLoIkTc=,tag:VMXaP2pB7h37Grt+9UDBoQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,110 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "sonarr";
image = "ghcr.io/onedr0p/sonarr:4.0.4@sha256:9c78b3a37af6e814062e4a631c25ad181c800ae11d21acdfd26c843da9e4a42e";
user = "568"; #string
group = "568"; #string
port = 8989; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
containerPersistentFolder = "/config";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
sops.secrets."services/${app}/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = config.users.users.kah.name;
inherit (config.users.users.kah) group;
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
dependsOn = [ "prowlarr" ];
environment = {
TZ = "${config.time.timeZone}";
PUSHOVER_DEBUG = "false";
PUSHOVER_APP_URL = "${app}.${config.mySystem.domain}";
SONARR__INSTANCE_NAME = "Radarr";
SONARR__APPLICATION_URL = "https://${app}.${config.mySystem.domain}";
SONARR__LOG_LEVEL = "info";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Sonarr = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "TV show management";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_SONARR__API_KEY}}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
sonarr:
env: ENC[AES256_GCM,data:qqHY3p092WfsIfWdKXvVJg==,iv:89h8Xw10HkOyN3ZlpeeEXvB9N2MrOopD/1AL51NobuI=,tag:Bk1MJcb58K0tmccGBlOMiQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxL09DMDJFd1RnZHNwbjFQ
MmkzSCtRWHN3Ri92cFhUUGIreGQ4MUJMOGxBCmlFSnBsM1RKclpGc3dad0w2eEdj
MkVLYUdWYnBRQ2VSYWVmcjFlK2xpU1kKLS0tIHIrUEtINWtJbmpqcUticmpWbWc2
U3ZFRUExV2lHUG1RZ09aVFU2RTZuTjQK+jetUpJHMLJwVxazQBDlhrvZrrHGm9ks
5xUr6jkpE6zmg8W1DVQ4rShfDyCpTbqsqfx2zV1wJ9Poe24lMNw4LA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6amQ2QUhUWDlqelBFWkFu
N2VodmIrMnRnWjcvZThYVVpXWGl0Mk5kUEFRCm1iczQrU21wc2NlN0ZXTE9YOUZp
S2hSaExab2QzTUZhTHhsYjRwOVE0MlkKLS0tIG8zVDFqWG94TStEZmx5aEZNRmQw
eGs4YnFMWmhTOGhLQ0VWdFlkSGkrM1EK0PbiqN11i9xOgFiMLy8715mkwog1iZgm
QjCbFL+MbOqcpbfMStupHrg34aP4mgmcjBQlTwqlbhn1K3mqhjQu8g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBndTFMNEJvYjFYUTRzRDBW
ZmJwSmxWeEJOYTU1a2JUVFpmcHAzb2Zyem5JCmQ4QWJGY3RCVmNoeUwyaUVDeERz
a05kSDFaMHl1S2JPNkw1ZnJZYmZSYXcKLS0tIEk1KzlmTkVWVDlacFh4Q1FqTzJT
bWNJYTZURFJmeXYzbjdna243RmpZdkEKM9Ixfy0eE8iGGTUcY92NhDYuJ/oOuiCT
pucwAuVGlO/ZJxvByrGHmfHp8pvsAdE1H46nIXssqb+LoZOnl1nSWw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3SmdHOVhCL0V5a21GMjQ0
M1JES0dKclBmcjNSdWFPTXd6RzQ2WnhUd2pVClliS1pncHZld0NGYzFtTE90OWhy
V3lweGUvM0ZnV0lObDdBaFpLSGpaQ1kKLS0tIDduQXVaRzZqTUwrTjVmRTFYa1lN
M01kODQrTzlOQUJmNmlmcXpEdUNqYUEKtDP4fGNkOFbXVFt5612CPGFspsM/PuhZ
mU/7mEWCNauZ74VrHWVtEYYI6bvr8Z6BszJe0UF5Wt4ZL0QVObj5Fg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:qPTN+la1YmZ/RpBf2jgYnc4LfvEInH8jlvX+5AICIXYB9RhF9zaWAohn4lUch/rcMaZsBSCiqvS3xpe+FgKU567hePRLgaezl9lDUya/RYynJJ8i8FG3Sg6EgMaqqn8naDl9Ywo3kCvDl5LRLe5u+gdkHXzLIQ7O/44BpcKusn4=,iv:nl2MsL6bIZN3r/HUBeDd9JQo5iYN/yTboq3r/8lWKQg=,tag:gWTgEF63PyGQrVEFx61SOA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -56,21 +56,7 @@ in
};
};
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
Backrest = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Local restic backup browser";
container = "${app}";
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "infrastructure";
url = "https://${app}.${config.mySystem.domain}";

View file

@ -1,157 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "calibre";
category = "containers";
description = "eBook managment";
image = "ghcr.io/linuxserver/calibre:version-v7.10.0";
user = "0"; #string
group = "0"; #string
port = 8091; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backup = mkOption
{
type = lib.types.bool;
description = "Enable backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
users.users.jahanson.extraGroups = [ group ];
# Folder perms - only for containers
systemd.tmpfiles.rules = [
"d ${appFolder}/ 0750 ${user} ${group} -"
];
## service
virtualisation.oci-containers.containers = config.lib.mySystem.mkContainer {
inherit app image user group;
env = {
PUID = "568";
PGID = "568";
};
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix/:/media:rw"
];
ports = [ "${builtins.toString port}:8080" ];
caps = {
noNewPrivileges = true;
};
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts.${url} = {
forceSSL = true;
useACMEHost = config.networking.domain;
locations."^~ /" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true;
};
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
warnings = [
(mkIf (!cfg.backup && config.mySystem.purpose != "Development")
"WARNING: Backups for ${app} are disabled!")
];
services.restic.backups = mkIf cfg.backup (config.lib.mySystem.mkRestic
{
inherit app user;
paths = [ appFolder ];
inherit appFolder;
});
# services.postgresqlBackup = {
# databases = [ app ];
# };
};
}

View file

@ -1,43 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "cross-seed";
image = "ghcr.io/onedr0p/sabnzbd:4.2.3@sha256:8943148a1ac5d6cc91d2cc2aa0cae4f0ab3af49fb00ca2d599fbf0344798bc37";
user = "568"; #string
group = "568"; #string
port = 8080; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
configFile = builtins.toFile "config.js" (builtins.toJSON configVar);
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
cmd = [ "daemon" ];
volumes = [
"${appFolder}:/config:rw"
"${configFile}:/config/config.yaml:ro"
"/etc/localtime:/etc/localtime:ro"
];
};
};
}

View file

@ -1,19 +1,6 @@
{
imports = [
./arr
./homepage
./gatus
./sabnzbd
./qbittorrent
./plex
./tautulli
./backrest
./searxng
./factorio
./whoogle
./redlib
./home-assistant
./calibre
./ecowitt2mqtt
./gatus
];
}

View file

@ -1,158 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "ecowitt2mqtt";
category = "containers";
description = "Weather station to MQTT";
image = "ghcr.io/bachya/ecowitt2mqtt:latest@sha256:91d31b6db0c00021580f8890341cbbea44c8835dd8eb9f80f811dfcd6ac29c24";
user = "nobody"; #string
group = "nobody"; #string
port = 8080; #int
# appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backupLocal = mkOption
{
type = lib.types.bool;
description = "Enable local backups";
default = true;
};
backupRemote = mkOption
{
type = lib.types.bool;
description = "Enable remote backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
sops.secrets."${category}/${app}/env" = {
sopsFile = ./secrets.sops.yaml;
owner = user;
inherit group;
restartUnits = [ "podman-${app}.service" ];
};
users.users.jahanson.extraGroups = [ group ];
# Folder perms - only for containers
# systemd.tmpfiles.rules = [
# "d ${persistentFolder}/ 0750 ${user} ${group} -"
# ];
## service
virtualisation.oci-containers.containers = config.lib.mySystem.mkContainer {
inherit app image user group;
env = {
ECOWITT2MQTT_MQTT_BROKER = "mqtt.trux.dev";
ECOWITT2MQTT_MQTT_PORT = "1883";
ECOWITT2MQTT_MQTT_TOPIC = "ecowitt2mqtt/pws";
ECOWITT2MQTT_PORT = "8080";
ECOWITT2MQTT_HASS_DISCOVERY = "true";
ECOWITT2MQTT_OUTPUT_UNIT_SYSTEM = "metric"; # Come on guys nobody want to use freedum units"
};
envFiles = [ config.sops.secrets."${category}/${app}/env".path ];
};
# homepage integration
# mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
# {
# ${app} = {
# icon = "${app}.svg";
# href = "https://${url}";
# description = description;
# };
# }
# ];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}/data/report"; # check the reporting URL for 405 'method not allowed's
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 405" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
# I dont need/want ssl for this one, weather station expets http
# useACMEHost = config.networking.domain;
# forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
proxyWebsockets = true;
extraConfig = "resolver 10.88.0.1;";
};
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
# warnings = [
# (mkIf (!cfg.backupLocal && config.mySystem.purpose != "Development")
# "WARNING: Local backups for ${app} are disabled!")
# (mkIf (!cfg.backupRemote && config.mySystem.purpose != "Development")
# "WARNING: Remote backups for ${app} are disabled!")
# ];
# services.restic.backups = mkIf cfg.backups config.lib.mySystem.mkRestic
# {
# inherit app user;
# paths = [ appFolder ];
# inherit appFolder;
# local = cfg.backupLocal;
# remote = cfg.backupRemote;
# };
};
}

View file

@ -1,50 +0,0 @@
containers:
ecowitt2mqtt:
env: ENC[AES256_GCM,data:jyDAIs+y8kk5jI88bC//YQ==,iv:dbNmqstFgVN5aNWv7rDAybcyt65VADHyL4DSRA/F0qg=,tag:rRQNUvU/q+TZKa/QCLSRtw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOK2tBVjlBaFo1VVJ1ekpx
b0xNU0VMZk4rNVVHR241S1djMjlIcTI3V20wCkEzejErbEZnNVNVKzhmcjIwVWJU
dU5vVVpGZi9OR1RXcW9NQ1d1UDBqWVEKLS0tIDdBRGtwcmZsamFMRVRvcWdZME1y
OTZ3SzNyWWMxTmxwOUpnTTExbTVQZWMKP+39o6T1Ml0bBFeCk9bKsWcWy19xxVQy
cqanZLReUgvYJKHkYV+F0IAUp6Hk/bTStOapN9qjqkZtU9c09dRJ/g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxQTFCdEhMY2hkaDBJUG5P
cmkyeTZUNUpnSEpIWWVpSUNvOUhyc2JnODJrClFuK0ZGcENYRkhCbnR4dzMrMm1k
SWg4ZkJ1Y0Q3TENUQ1FVSE5XVFpLUkkKLS0tIDBoVkd6UUlrdFp1dEpDWHdwV2s4
bnoxd3RxQWhWY2hJWEpDT3N4RGp3VVUKb3q6vXN3giYz34zIc0oYpG6Bibnoqjyj
62k3ym5rjXlSLLnSk+ABQ+OwCZb6hzNT9u7I6hkmnLQhGgX0loqz3g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVUjZudFBUU2VDdzcveUZr
aUI5Z00xMEQrejAvQS9LdGxnVXVocXhLS2hzCk9nTk9lb0ZpT3FZWTU4eEYyYVJt
UXFWTGNwUkJpcnBIcnNRTSt6UHkzcEUKLS0tIDkxdzk0cDc0andKRVlEdEo2L000
eXJkRUw1ZEY0bDhxVUJsSGN2WGtZNUEKSLSZCBWcauFt4TvTPSsklYKRfcHrSVob
B6CClhyG4mgrG0C9TZzaqw9ZXGoHyukWAOXY6wTAKdFliNvk8PzAfg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3dW05N3l3T0dyT0pBMDdT
NllmNlZnUVlwV1FJeWhueHdTZHRuQlFVWlFrCjhQODRiSkc2bmhqWmZ4bkhyOWNI
Z3BjNVhsSkFRQWpBdGpaaitlL2lwUTgKLS0tIHBrZm0vSHNYdktwd2w5aGdpTTNI
dGE2bTlQcm1PNUZkK1lVNXpDUEYrd2sK12fPbfKuiWMm8HD/360QS8MrdWS2eUgy
g3BaWucH7GFa1veVw3uBqeFMDW/ZisC27w4lS6buQVq4TcHybbtD7Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:U4Q/RboQRdfyTsSqxppc86xRNQpTE7vZ2zujrWU5SZ+nJho2H+uXkbFQrXFasgBy5gxT2IJtcjd0k/logVMc5KMd+whwf2q35qKpAtIbEDXYGfUsvrz2UMl/K4Kq4tM21zCzMHWQWiSXPSGDN9BE8QiRbZKjGCZ4Mp+yFv+1vrA=,iv:8Q0adi1GXu4AnH2pYyI18AsBx5KVxAYQibIEo4VgaFI=,tag:9LSw+hh1b5wuqb8POyeU1w==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,101 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "factorio";
instance = "freight-forwarding";
image = "factoriotools/factorio:stable@sha256:fae8a40742bd6fc42c92eac3956ad36737cf0ce5a31d2793438b65ad8b50d50a";
user = "845"; #string
group = "845"; #string
port = 34203; #int
port_rcon = 27019; #int
cfg = config.mySystem.services.${app}.${instance};
appFolder = "/var/lib/${app}/${instance}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app}.${instance} =
{
enable = mkEnableOption "${app} - ${instance}";
addToHomepage = mkEnableOption "Add ${app} - ${instance} to homepage" // { default = true; };
openFirewall = mkEnableOption "Open firewall for ${app} - ${instance}" // {
default = true;
};
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0755 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
# make user for container
users = {
users.${app} = {
name = app;
uid = lib.strings.toInt user;
group = app;
isSystemUser = true;
};
groups.${app} = {
gid = lib.strings.toInt group;
};
};
# add user to group to view files/storage
users.users.jahanson.extraGroups = [ "${app}" ];
sops.secrets."services/${app}/env" = {
sopsFile = ./secrets.sops.yaml;
owner = app;
group = app;
restartUnits = [ "podman-${app}-${instance}.service" ];
};
virtualisation.oci-containers.containers."${app}-${instance}" = {
image = "${image}";
user = "${user}:${group}";
volumes = [
"${appFolder}:/factorio:rw"
"/etc/localtime:/etc/localtime:ro"
];
environment =
{
UPDATE_MODS_ON_START = "false";
PORT = "34203";
RCON_PORT = "27019";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
ports = [ "${builtins.toString port}:${builtins.toString port}/UDP" ]; # expose port
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ port ]; # I dont use rcon so not opening that too.
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{
name = app;
group = "media";
url = "udp://${config.networking.hostName}:${builtins.toString port}";
interval = "30s";
conditions = [ "[CONNECTED] == true" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
factorio:
env: ENC[AES256_GCM,data:VuRK4vLrpPgmr41OfN6xCw==,iv:Z3vlV9WZdcZ9fZXSjrQ67O4oec0xDHcg2tMqAi8E1hM=,tag:E/y2cCjeDcoS8itM2uSEOQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRV2Y4V3gxaUEzeThaQW54
QVhXZnNoMlpQaksxZ0pCVGZkdWpucUNUaUE0ClNpbWVETlFTRDk1NDdiYjJWZ1ND
NFFCMnFRa3ViazB5dG1FWHRNMk4zWVkKLS0tIG9sTHEwWlhGZUNKV1VPSWZpWlcy
ZjVoQjBsMjVwYnh6MTdVWFZGNm9UbW8KC2FM/dCsmmQ0q9uiwe9zeczJNabJnBVh
sLMJ/X41hGlb8G0dGVRnBbbXqRelSLyCgFkgpcUO8hFNKyW9WtG4Dw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5dVBVdjNLTG5iWG5kYXAv
K0ZrZzUxaEZzN2UvVFlneHpyOWtudG5obmlvCjlscXhYRnFuZEwvdDFZNWhnazhk
KzFBZzZVMksyaHl2SzFKRnZvT3UyUW8KLS0tIGN4bFRVMVd3SzFzRjJoVFFKM0E5
UHpyYkE3OVRoQWErN0JBcm96MmltdDgKliCv1TytM2xKWhNCbAyOkjpky48J+/pb
nnrSd1+RiZvICH3W4H2wKImTsPx2Rs5eRwju9eG/jW/RKXgiG9Kbvg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFU0VwRUJsVnhlQk91VnhH
NnFRZkZGRTV5REJPT2duRkN3cGN6Wkl0cjNzCjgrcVNhTkM5cXIxbkppdm9yOUww
UTFvMnYyWnlzdXZrNitTcUFmU2ZjMm8KLS0tIDFEc0RzU2YrRjhtbDY4c3dYTTRQ
VEJvSzlWTElJZWQ1U3I3SUFFOXYvMFEKqvLQbs9GaW/Y/IjUpsyqpAwADGjC2rUL
l6ShXZ8L5rvSvN0eArgUmTyOH1gCzx0nt3P4Q0u/KVMkjetqISatqw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxYmo5WkJwTlVGQUlIeXBE
VXNpUmNFRWJ5cWI4Yzl4NEt2Qm9CTXQ5a2pJCnNYdmMxaHRIUE53bmwvdUc4UzZr
d3JSVGx1eWFOTy80UG13enBwVUFCVk0KLS0tIHVJeGc5SDFoZXNKdGdSYVk1azZt
YWJvQmlWNm01Vi9rRUZ6eG51MENTaEEKUaq7S1z54TITkZoNKhgn+zWdL3XZbGgr
1XrQ73ITvDeMMal0EGMJ7znj1xhOioplMINqGE8gQX3xUVaNLtkhpA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:q4gp2pazpoheErkCDwDYSRLzw0MmpAGGEtGC/opwRmsjATDIA5RMF7BW+0s+LqC/mIUCWiV803jNRH0RHkyAM+B1zkgx0IMyTDLCeIKphMDEQHHwnS/kBSyFQNimEXevdkOVe1x4W/Uyj048o0n4/T81ivQc7b3Im3kBj5JRSIQ=,iv:VqLb3FNS7hNpvGBE+WC3em5USqbh1l738UjazXTFQMM=,tag:f23h1kKy8ux2uo4QBy9GYA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -115,21 +115,5 @@ in
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
"Gatus Internal" = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Internal Infrastructure Monitoring";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
};
};
}
];
};
}

View file

@ -1,6 +1,6 @@
services:
gatus:
env: ENC[AES256_GCM,data:bqAAKTvPB4tXACy2EiuqPw==,iv:wN6h6yOoW5LiZileoHWk0lxgFlDkf7slrv3koYtMb9o=,tag:iXI4IKRZLxO0YoJ0dK7nJA==,type:str]
env: ENC[AES256_GCM,data:K3OMquhrq0GwltyBC0+ljA==,iv:sy65e+JNYFmxkapd98KdknS6RIdysCuypA7GkdjwbvM=,tag:asCMBItfHCkqE/dT2IlPxQ==,type:str]
sops:
kms: []
gcp_kms: []
@ -10,41 +10,41 @@ sops:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVempGU2FMYTNOSEtPdTVO
WS9qRHQ0alFtYUxXTk1sa3ltcU1RQWtGR0FvCk40aUVkbVBBdmVaTTdrclhzWHJY
ME4wc0F3bjFXWmxLZXE1UmxyTnl0ZEkKLS0tIHRyOFNCY05CdXpLRURpTzV4MW5P
dTM1N2FlRWVvVXBmaGw5QUViZEpndDQKWKVtD50hfJS2AR+3VxGGZXyMcdsawx6s
lxatCKMnWW1VWpz50Il16vYAnIttPeN5C9qBc5bbVdmPcG+pC6Miug==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1NFQzOHZ6RjRLeU5FWEQv
cmhrUkI3T2ZmcU9FNmZPWkhyVEIrZU5rZWg4CnNRVlVuV0VtN25QYUx3bjVZbmdU
emgrUXppWTFNYklZYnN4cDRRVk9CN1UKLS0tIEdiK0FGYkw1UWE2QUVLa0RndkxW
S2hBTExyOU5mSFJaNWRsK0VXUElwQlUKf+XUWwIkQ2UUk9N99Ern2dL8NPttuCvC
O2ED+sj17lm8H1Qm9GHB7cMAF4JJB94TvIUsRH7+q/jJe2WETHlDVw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0VlRhTWtsSGw5WENMZDl6
OEx3SWxYQWZSc2tmc3VsS3BJNjNJN2dpSkZJCi9KMWZlb3pwMjErNHR1VkgxQ2VR
Y1lzYThjOWNpTCtRNldJak5WSnZBUTAKLS0tIGhwWTJUNG4wejdIUkM0OWJEek5U
Sy9PQ1F4ekFqRUZ2RnIvTzJxaDFnRmsKFpDLBvNKtDRN2KPLSFsd7nFM63fZvBGk
3bLGz5L72kKrcqsha08ePtPGi1N4s3xGFmNPXZC5TUPAEkRcJ2PVwQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjQXYvNlpuaENwVEJuSUxj
WllLaWZTdVo0Z0FQRFFZazJpTnZxUFNuS1VjCmRPdEwvVjZHazI5TDNuaVl0MDlh
Zko1eGEvYkhRcWZpV3NRdGM1VnFnWFkKLS0tIDNqVTF4bTUvTTFuL3lZa1l0VkZj
bmdZVVZ5MUUyZWE2NFovRVVyalg2YzgK+K/9Nd4KJ3EmiebAci5rwAJf308y4a/s
d0x8asfxk00YDRcZbxsNcMCLxFX+PUUol04GMz8SzImQrDcl8FATWg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtd3VLOFhaczRybnIzQUpo
NWVBS0dlMUM3ZWN5eHhmaFhZV2FzQlNQeEJVCnErYTZkQzVZazh4a0dNY1A3d2N3
enJpUEpTOGN5eGVFQ29XSXdtZjR4ZmsKLS0tIExkck1FcEtQTTh5RzNjL1Rvak9z
Um9LcnQ5akZqdmdkZTg1SnpzWVVTeTAK04JYXziITePLRUqLojzYni7EwszgKgeS
mCfxGm9UKaUiEc7UWYoTWw3OonyShw3AiNXSTBo/asbyK5aQuSgnjA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArZW9XTVM1Z0JjMGJNQnND
cW9aNW1RRGNBOSt0V3RSODVQK21hVkxLR3ljCnBia0pvTmhNbFNVSDNxNStIWjEw
eWJIRTZvVTAwMzhwcHlIbDRxQzlBRUkKLS0tIFhBV0paeGxRcVU0ZnVncGM1ODAr
SitqR3UzNnhyaUp3UFZrZ0xHOEhXZ0EKc9WuFf6FAba4lByVxfH+hGrq/2imOzjL
4oWMfV6gucLa5+9ko2PP0hMrT8/KAtnMX7z062Pg9eEW0E0U8KaKzQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzOEo4S0lTYk1ZcjA2MUQx
Yk1XUFJxWUIrQW1wT1NzKzFwbjg2ZkkvdzNJCmdGWE9PRHN1cjl0R0ZpWVc5WWVj
TkdRUFVMK3JkSld5NkthenNubWJMOE0KLS0tIGp5OUUvTnh2cUZoTXJ6SFpKMlMy
UjVsN3RzT2psMk9ObWtaSFZKUWoreEUKqTjC55QrJlbNHcLZ5asr125QQMgJ8z78
sm7dsKAhdOKHjLvW9Cqf68/zsEXeToiB40SC94eFXHs4UOMYbKcN0g==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXWUdDUzQ2YjZsZHQ3OUR3
bmhjY05IM0J0bXlvL2ZRK09DSzJpQWQ1UEhVCnkwMVB6c3pTcFRQRitaZEw0MUdU
SnpORnV2TkxRK3FYRVBVZWhGQVp1YzAKLS0tIFZWbGJabW9aUnpxT2h5QVdSbDNk
aHFPYWRwRS9qMmd4QUFPL0JCbEdVb3cKg4XvsbpCTJrx17y2SzKotqA0wNo6Tdht
VXXUwiD48ZKP8WxuGCAJQbmoDWozX9b27HDwWz04fcmxxdQ7TL3ShA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:mXCcrWWhheFFHCm1cqblLDV1N/of9WbNZDBcCeVtnPxeS+VF2f+Yovy/DT5PH029ppg388Un0lS/P+ZYUhwGGQLaY9hHbTryZ/474EkBCG2B20mEZvMFGczbCkFCnx1zA7wePm9QHRqMa5S2PnsWn32SaP4GfBz/w8K++BUw8/Y=,iv:usWSlCtgTWNrEDfatE0RQrSjtv6buk8N3Ai4zlT6osY=,tag:DwlALfatw/1IK1TIUmhRSQ==,type:str]
lastmodified: "2024-05-18T16:39:41Z"
mac: ENC[AES256_GCM,data:Otd3VL5QNOmddoEeszeOioKh5EVXMKzLRZ66WhB3eA5TdTZ2s49xTplHHd3vj1v9GGYkm8zrF4JBrz2llOZxByR9nnHmY8eRANapy6/bE9c89cAkiy25mNF5AE0UKX5/Ds4lao0D1PcebBLLGu2IBCXoDs83v5z3Wn3LHqaZPG0=,iv:TaSVuY/gAlAjCzWksg5BDFlF3YAyVWGUNvJI+wrCcXU=,tag:yR7ZhTg+Z3FYZZfXx7dL/A==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,97 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "home-assistant";
image = "ghcr.io/onedr0p/home-assistant:2024.5.2@sha256:76e416dd4ab2f14ca9be120617fe69f51ad335c284352c189a0315954bed4b4e";
user = "kah"; #string
group = "kah"; #string
port = 8123; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
sops.secrets."services/${app}/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = config.users.users.kah.name;
inherit (config.users.users.kah) group;
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
environment = {
HASS_IP = "10.8.20.42";
};
environmentFiles = [ config.sops.secrets."services/${app}/env".path ];
volumes = [
"${appFolder}:/config:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
proxyWebsockets = true;
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.homepage.home = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Home automation";
container = "${app}";
};
}
];
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; user = "kah"; group = "kah"; mode = "750"; }];
};
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app;
user = builtins.toString user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,50 +0,0 @@
services:
home-assistant:
env: ENC[AES256_GCM,data:8rZWXEsMTYMRy58P+aPu2Q==,iv:EBtDsAuuC6uxJ+LC2+5v54S+zP7OBs5KsnqiHXslDRo=,tag:vizmALq1bV5beiLqRnduDA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBucHI1ZW5NMXVhN3pQSC80
aEg4TDJONU1DWFlXTHNsdEJiS2VxcXpYL1hrCkR6bDFaYWtxQmhJemdLKzVyUGRa
WDBVRHFiNGlYQTZkaU5SWU9qdmFrbUkKLS0tIFAxUUxJdFlEQXVmd0pTY05iK3pM
NmdVdDA3WFR6c3BRZTJVM1Fza0NXZEEKxl5C7+GfCwbr+6sOAMXOt0Tcu9W65M9T
Enux8Cr2afdPc6fKtKh1LS38wp7gtDI0/GKO3xQ6jYhOi3m3pHvfxg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOWTJZck5yYWIwbG42aDBD
cm04SXFKWGVJUlhpWEhEMGNVTnAzekNMS2hNClBsTWRDWWUxSjg0bkd4OHNYajBo
RmNJMWtyOTNxYTUrNmhQQURVT1hEN2MKLS0tIHZwalhob3JnZWF5RW9vMWlmeVdI
VjAwNUN1SkprKysyMWJSTmlHU1dYOGcKGA2Jk98ZMSAaWTdhL3sN5BSBMAlXv4Zj
IONPTFS48yoAiWFjMAUUuQfrYF38MJCTFVRrx66DGEWqf5XRAmxedg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXc0FCOUcxOXJ4bEhRVnlN
bWJWd3pwTGw1eG5ObFNtSjM4ODFyZjY0NldjCmpSMnJWMVRWc3ZqcTNjeGFFUG9I
YlFEeGdrSTYrZzlxZ0tVcW5nWEw0bUkKLS0tIHkzRTN5RXZackRnMkdDNmZIRjJx
R3MxN0VETS9LMnpvRFp1bEN0UmM4Rm8K11D35Yf43EkkKxi5bPX1/LJsmejnwkNu
243GBpNR3vS2DOhf+q9IpAULdWjPnO9UQUZxzGxZmlekJ20hwXjLLw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPcFFPUm5DTFZyWGthTHE1
UExFZUlNNUVHRyt6OGhCeWRnZS9BdCt6Z1JNCkZRc29wVURmNnJmdHB6bkNTZDkv
UmxIT24zSitCZldGNXl5Wk9nSy9pVTgKLS0tIFhFYThPVGVjbWRDSWdzdEhUODFi
UzFTZTQzMVlHb1Vjc1p4NC84cUFOaW8KoW7zvAvXxDVXCWYi+InWK4zK2nta+ydS
i1pd5uxdTFqPLt+GR9HNpcaIPUXOv2szIF24IKGAXitP6ysYp3bLsQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:12Z"
mac: ENC[AES256_GCM,data:G7QG5R9tbsAKyLsQDcg5P8PLufiNerP1JjddxGy+kGu6rRWnyZ0HOPVpJN0xv6gbRiUMWhhUt/V39O/bK9OSc/FzN3lZf6pDT9PAfYGnCY3hfyDBYN6fiJooovqGKkkBMS97rt+00FUPJEjwRLgJAK3MpdA65F2xJxXkSvQbzLg=,iv:749n6L8hKE+Ng17JgllSv4nL17sDSD40ZSerUhDXCTM=,tag:sCODC6LTpEHcVDoFBwT17w==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,321 +0,0 @@
{ lib
, config
, pkgs
, self
, ...
}:
with lib;
let
app = "homepage";
image = "ghcr.io/gethomepage/homepage:v0.8.12";
user = "568"; #string
group = "568"; #string
port = 3000; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
# TODO refactor out this sht
settings =
{
title = "NatFlix";
theme = "dark";
color = "slate";
showStats = true;
disableCollape = true;
cardBlur = "md";
statusStyle = "none";
datetime = {
text_size = "l";
format = {
timeStyle = "short";
dateStyle = "short";
hourCycle = "h23";
};
};
providers = {
openweathermap = "{{HOMEPAGE_VAR_OPENWEATHERMAP_API_KEY}}";
};
};
settingsFile = builtins.toFile "homepage-settings.yaml" (builtins.toJSON settings);
bookmarks = [
{
Administration = [
{ Source = [{ icon = "github.png"; href = "https://github.com/truxnell/nix-config"; }]; }
{ Cloudflare = [{ icon = "cloudflare.png"; href = "https://dash.cloudflare.com/"; }]; }
];
}
{
Development = [
{ CyberChef = [{ icon = "cyberchef.png"; href = "https://gchq.github.io/CyberChef/"; }]; }
{ "Nix Options Search" = [{ abbr = "NS"; href = "https://search.nixos.org/packages"; }]; }
{ "Doppler Secrets" = [{ abbr = "DP"; href = "https://dashboard.doppler.com"; }]; }
{ "onedr0p Containers" = [{ abbr = "OC"; href = "https://github.com/onedr0p/containers"; }]; }
{ "bjw-s Containers" = [{ abbr = "BC"; href = "https://github.com/bjw-s/container-images"; }]; }
];
}
];
bookmarksFile = builtins.toFile "homepage-bookmarks.yaml" (builtins.toJSON bookmarks);
widgets = [
{
resources = {
cpu = true;
memory = true;
cputemp = true;
uptime = true;
disk = "/";
units = "metric";
# label = "system";
};
}
{
datetime = {
text_size = "l";
locale = "au";
format = {
timeStyle = "short";
dateStyle = "short";
hourCycle = "h23";
};
};
}
{
openmeteo = {
label = "Melbourne";
latitude = "-37.8136";
longitude = "144.9631";
timezone = config.time.timeZone;
units = "metric";
cache = 5;
};
}
];
widgetsFile = builtins.toFile "homepage-widgets.yaml" (builtins.toJSON widgets);
extraInfrastructure = [
{
"UDMP" = {
href = "https://unifi.${config.mySystem.internalDomain}";
description = "Unifi Dream Machine Pro";
icon = "ubiquiti";
widget = {
url = "https://unifi.${config.mySystem.internalDomain}";
username = "unifi_read_only";
password = "{{HOMEPAGE_VAR_UNIFI_PASSWORD}}";
type = "unifi";
};
};
}
{
"Nextdns" = {
href = "https://my.nextdns.io/";
description = "Adblocking DNS";
icon = "nextdns";
widget = {
profile = "{{HOMEPAGE_VAR_NEXTDNS_TRUSTED_PROFILE}}";
key = "{{HOMEPAGE_VAR_NEXTDNS_API_KEY}}";
type = "nextdns";
};
};
}
{
"Cloudflare" = {
href = "https://dash.cloudflare.com";
description = "DNS and security provider";
icon = "cloudflare";
widget = {
key = "{{HOMEPAGE_VAR_CLOUDFLARE_TUNNEL_API}}";
accountid = "{{HOMEPAGE_VAR_CLOUDFLARE_ACCOUNT_ID}}";
tunnelid = "{{HOMEPAGE_VAR_CLOUDFLARE_TUNNEL_ID}}";
type = "cloudflared";
};
};
}
];
extraHome = [
{
"Prusa Octoprint" = {
href = "http://prusa.${config.mySystem.internalDomain}:5000";
description = "Prusa MK3s 3D printer";
icon = "octoprint";
widget = {
type = "octoprint";
url = "http://prusa:5000";
key = "{{HOMEPAGE_VAR_PRUSA_OCTOPRINT_API}}";
};
};
}
];
services = [
{
Infrastructure = builtins.concatMap (cfg: cfg.config.mySystem.services.homepage.infrastructure)
(builtins.attrValues self.nixosConfigurations) ++ extraInfrastructure;
}
{
Home = builtins.concatMap (cfg: cfg.config.mySystem.services.homepage.home)
(builtins.attrValues self.nixosConfigurations) ++ extraHome;
}
{
Media = builtins.concatMap (cfg: cfg.config.mySystem.services.homepage.media)
(builtins.attrValues self.nixosConfigurations);
}
];
servicesFile = builtins.toFile "homepage-config.yaml" (builtins.toJSON services);
emptyFile = builtins.toFile "docker.yaml" (builtins.toJSON [{ }]);
in
{
options.mySystem.services.homepage = {
enable = mkEnableOption "Homepage dashboard";
infrastructure = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
description = "Services to add to the infrastructure column";
default = [ ];
};
home = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
description = "Services to add to the infrastructure column";
default = [ ];
};
media = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
description = "Services to add to the infrastructure column";
default = [ ];
};
};
config = mkIf cfg.enable {
# homepage secrets
# ensure you dont have whitespace around your ='s!
# ex: HOMEPAGE_VAR_CLOUDFLARE_TUNNEL_API=supersecretlol
sops.secrets."services/homepage/env" = {
# configure secret for forwarding rules
sopsFile = ./secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
# api secrets from other apps
sops.secrets."services/sonarr/env" = {
# configure secret for forwarding rules
sopsFile = ../arr/sonarr/secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
sops.secrets."services/radarr/env" = {
# configure secret for forwarding rules
sopsFile = ../arr/radarr/secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
sops.secrets."services/lidarr/env" = {
# configure secret for forwarding rules
sopsFile = ../arr/lidarr/secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
sops.secrets."services/readarr/env" = {
# configure secret for forwarding rules
sopsFile = ../arr/readarr/secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
sops.secrets."services/prowlarr/env" = {
# configure secret for forwarding rules
sopsFile = ../arr/prowlarr/secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
sops.secrets."services/adguardhome/env" = {
sopsFile = ../../services/adguardhome/secrets.sops.yaml;
owner = "kah";
group = "kah";
restartUnits = [ "podman-${app}.service" ];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
environment = {
UMASK = "002";
PUID = "${user}";
PGID = "${group}";
LOG_TARGETS = "stdout";
};
# secrets
environmentFiles = [
config.sops.secrets."services/homepage/env".path
config.sops.secrets."services/sonarr/env".path
config.sops.secrets."services/radarr/env".path
config.sops.secrets."services/readarr/env".path
config.sops.secrets."services/lidarr/env".path
config.sops.secrets."services/prowlarr/env".path
config.sops.secrets."services/adguardhome/env".path
];
# not using docker socket for discovery, just
# building up the apps from a shared key
# this is a bit more tedious, but more secure
# from not exposing docker socket and makes it
# easier to have/move services between hosts
volumes = [
"/etc/localtime:/etc/localtime:ro"
"${settingsFile}:/app/config/settings.yaml:ro"
"${servicesFile}:/app/config/services.yaml:ro"
"${bookmarksFile}:/app/config/bookmarks.yaml:ro"
"${widgetsFile}:/app/config/widgets.yaml:ro"
"${emptyFile}:/app/config/docker.yaml:ro"
"${emptyFile}:/app/config/kubernetes.yaml:ro"
];
extraOptions = [
"--read-only"
"--tmpfs=/app/config"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.gatus.monitors = [{
name = app;
group = "infrastructure";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
};
}

View file

@ -1,50 +0,0 @@
services:
homepage:
env: ENC[AES256_GCM,data:nqlPgxgNmoQNPX7ASt2VFQ==,iv:0BcE5l0wLH2/Cy8uHNzZbMOkrJIRfsgzb12SPt5380E=,tag:TheQzCRAI/kASwpQUKMZTw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3Y1Z4M2p5YzN3QkRyRCt2
RkpxZnpoTXh5Q2NPdU92RmxVa3hGUFNCeEJvCmFtYlZIbWZhMitXTlBLK2RRMXBD
VmVmU09HaDhtdVRQdEptWXhla1R4ZTAKLS0tIDVKeWZYUnZNYkxvMUJUTXd4bHcy
SXJXS3BIMmJBR0RoR1NPS3ZrVEh4VTQKi3IIvONwfj4Jk60ZLohXD1m5Vgc2QmWw
d6v/aR3CJuR8MLYKE4copWF2lz9LoqwEmCy4GZZfa0HGUI67+XntYg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1MG9BeCt0UzJ3cTh0Mito
WnBoL1pLY3R3SVNMaXViMlBLZS9Rd3AxRTBnCjdOYnR1em9UdHdXZCt5VmNnQWwx
VVIxY09VRGUxd0dNRnVHMWg2bDBNajAKLS0tIDRabmtrYURKMGdUallWZEZscHFH
bnlndUx4ajhYak1oZVlZYTdsTEhva1EKFHHlMUtctfxY2DwtVNxPYZXp8lkQcTnq
G8b/w168XFqixs+L0H+nTwcAXf93r8QpPyXMbfaiIxcjLThkZTtC1w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQcEhTWGRFajUzRmw5UFdn
YWVmanpoRG9DZ2VUT3VjZ29GM3ZEM1p4cVdBCkVoL2wya1I1WDl3OGRldFl2MDVI
RHl1dERJQ3c3Q08xMU9LNDI1QW1IQjAKLS0tIFJDNWtoQlJWR1I4ZWxMQjNwQVcr
N0M1ZUpaZkxxTzBiamw5L1YxMWtESFUKCaCDbgI2RT2V31LfaUzU+SATw5YqeTIz
Am2Wfh3+z1WllTS3uO7se4zTMgPdXM1rySoDDwHMJbx0o8yy0n9N6w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuVHo0cXNMU0xJcUtzRGgx
cG56SHJmVkJDSlIrN3BHMzBFaFI4aHBRdG5NCk9BdUYxQXN0TjhvbGNkeTZOeCtO
MllDZFVJVlNEbUc2QloxOW1qYmZsVFUKLS0tIERjckdSNldxS0tQalZzTDNpdTJv
UEoxWk5MWUI1UlIwVW9JakFEMlZhUHcKjRAqw7cMt7FrFjoZJYOEhStpuAWo8akF
mygrfz46TnX2n7wA01M+bog/VqwAmcGjbdWdyUXQwzr3qE1DV2F/oA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:12Z"
mac: ENC[AES256_GCM,data:s1aUi3ZQPjw7ntOW8Sc7OXcBb14R6U0D9pSnzzFNx2ZoRDGaSEnmKktKlfUXQctaFF3spTbuF4ibUcrZODQA0bU659Y1iSMAe5Lr08gsICwwaAL4qpIEHSmjXa4ydwKFVnBrSNGowNSBDYy0vs1sFwEEFuGtiJsbxSpI2Zbamtk=,iv:84+2EA/8yX9FCDkS/pnE2TWAOnO9EyZbyPV2rF7mpX0=,tag:duNJI2Exe7zupuqIC+jCpg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,102 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "plex";
image = "ghcr.io/onedr0p/plex:1.40.1.8227-c0dd5a73e@sha256:a60bc6352543b4453b117a8f2b89549e458f3ed8960206d2f3501756b6beb519";
user = "568"; #string
group = "568"; #string
port = 32400; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
## persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
openFirewall = mkEnableOption "Open firewall for ${app}" // {
default = true;
};
};
config = mkIf cfg.enable {
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/data:rw"
"${config.mySystem.nasFolder}/backup/kubernetes/apps/plex:/config/backup:rw"
"/dev/dri:/dev/dri" # for hardware transcoding
"/etc/localtime:/etc/localtime:ro"
];
environment = {
PLEX_ADVERTISE_URL = "https://10.8.20.42:32400,https://${app}.${config.mySystem.domain}:443"; # TODO var ip
};
ports = [ "${builtins.toString port}:${builtins.toString port}" ]; # expose port
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ port ];
allowedUDPPorts = [ port ];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Plex = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Media streaming service";
container = "${app}";
widget = {
type = "tautulli";
url = "https://tautulli.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_TAUTULLI__API_KEY}}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}/web/";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
# excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,107 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "qbittorrent";
image = "ghcr.io/onedr0p/qbittorrent:4.6.4@sha256:b9af0f2173572a69d2c02eab8f701ef7b04f61689efe1c5338b96445d528dec4";
user = "568"; #string
group = "568"; #string
port = 8080; #int
qbit_port = 32189;
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
openFirewall = mkEnableOption "Open firewall for ${app}" // {
default = true;
};
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
environment = {
QBITTORRENT__BT_PORT = builtins.toString qbit_port;
};
ports = [ "${builtins.toString qbit_port}:${builtins.toString qbit_port}" ];
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
# gotta open up that firewall
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ qbit_port ];
allowedUDPPorts = [ qbit_port ];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Qbittorrent = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Torrent Downloader";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,143 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "redlib";
category = "services";
description = "reddit alternative frontend";
image = "quay.io/redlib/redlib@sha256:7fa92bb9b5a281123ee86a0b77a443939c2ccdabba1c12595dcd671a84cd5a64";
user = "nobody"; #string
group = "nobody"; #string
port = 8080; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backups = mkOption
{
type = lib.types.bool;
description = "Enable local backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
users.users.jahanson.extraGroups = [ group ];
# Folder perms
# systemd.tmpfiles.rules = [
# "d ${appFolder}/ 0750 ${user} ${group} -"
# ];
## service
# services.test= {
# enable = true;
# };
## container
virtualisation.oci-containers.containers = config.lib.mySystem.mkContainer {
inherit app image user group;
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}/settings"; # settings page as pinging the main page is slow/creates requests
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts.${url} = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
# warnings = [
# (mkIf (!cfg.backups && config.mySystem.purpose != "Development")
# "WARNING: Local backups for ${app} are disabled!")
# ];
# services.restic.backups = config.lib.mySystem.mkRestic
# {
# inherit app user;
# paths = [ appFolder ];
# inherit appFolder;
# };
};
}

View file

@ -1,68 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.redlib;
in
{
options.mySystem.services.redlib.enable = mkEnableOption "redlib";
# fuck /u/spez
config =
mkIf cfg.enable
(myLib.mkService
{
app = "Redlib";
description = "Reddit alternate frontend";
port = 8080;
user = "nobody";
group = "nobody";
inherit (config.time) timeZone;
inherit (config.networking) domain;
homepage = {
icon = "libreddit.svg";
category = "home";
};
container = {
enable = true;
image = "quay.io/redlib/redlib@sha256:7fa92bb9b5a281123ee86a0b77a443939c2ccdabba1c12595dcd671a84cd5a64";
env = {
REDLIB_DEFAULT_SHOW_NSFW = "on";
REDLIB_DEFAULT_USE_HLS = "on";
REDLIB_DEFAULT_HIDE_HLS_NOTIFICATION = "on";
};
caps = {
readOnly = true;
noNewPrivileges = true;
dropAll = true;
};
};
});
# mkService
# app: App Name, string, required
# appUrl: App url, string, default "https://APP.DOMAIN"
# description: App Description, string, required
# image: Container IMage, string, required
# port: port, int
# timeZone: timezone, required
# domain: domain of app, required
# addToHomepage: Flag to add to homepage, bool, default false
## HOMEPAGE
# homepage.icon: Icon for homepage listing, string, default "app.svg"
# user: user to run as, string, default 568
# group: group to run as, string, default 568
# envFiles, files to add as env, list of string, default [ TZ = timeZone ]
## CONTAINER
# container.env, env vars for container, attrset, default { }
# container.addTraefikLabels, flag for adding traefik exposing labels, default true
# caps.privileged: privileged pod, grant pod high privs, defualt SUPER false. SUPER DOOPER FALSE
# caps.readOnly: readonly pod (outside mounted paths etc). default false
#
}

View file

@ -1,94 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "sabnzbd";
image = "ghcr.io/onedr0p/sabnzbd:4.2.3@sha256:8943148a1ac5d6cc91d2cc2aa0cae4f0ab3af49fb00ca2d599fbf0344798bc37";
user = "568"; #string
group = "568"; #string
port = 8080; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
environment = {
SABNZBD__HOST_WHITELIST_ENTRIES = "sabnzbd, sabnzbd.trux.dev";
};
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Sabnzbd = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Usenet Downloader";
container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_SABNZBD__API_KEY}}";
};
};
}
];
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,84 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "searxng";
image = "docker.io/searxng/searxng:2023.11.1-b5a8ddfec";
user = "977"; #string
group = "977"; #string
port = 8080; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
configNix = { use_default_settings = { engines = { keep_only = [ "arch linux wiki" "google" "google images" "google news" "google videos" "google scholar" "google play apps" "duckduckgo" "brave" "startpage" "gitlab" "github" "codeberg" "sourcehut" "bitbucket" "apple app store" "wikipedia" "currency" "docker hub" "ddg definitions" "duckduckgo images" "bandcamp" "deviantart" "tineye" "apple maps" "fdroid" "flickr" "free software directory" "z-library" "lobste.rs" "azlyrics" "openstreetmap" "npm" "pypi" "lib.rs" "nyaa" "reddit" "sepiasearch" "soundcloud" "stackoverflow" "askubuntu" "superuser" "searchcode code" "unsplash" "youtube" "wolframalpha" "mojeek" ]; }; }; engines = [{ name = "brave"; disabled = false; } { name = "startpage"; disabled = false; } { name = "apple app store"; disabled = false; } { name = "ddg definitions"; disabled = false; } { name = "tineye"; disabled = false; } { name = "apple maps"; disabled = false; } { name = "duckduckgo images"; disabled = false; } { name = "fdroid"; disabled = false; } { name = "free software directory"; disabled = false; } { name = "bitbucket"; disabled = false; } { name = "gitlab"; disabled = false; } { name = "codeberg"; disabled = false; } { name = "google play apps"; disabled = false; } { name = "lobste.rs"; disabled = false; } { name = "azlyrics"; disabled = false; } { name = "npm"; disabled = false; } { name = "nyaa"; disabled = false; categories = "videos"; } { name = "searchcode code"; disabled = false; } { name = "mojeek"; disabled = false; } { name = "lib.rs"; disabled = false; } { name = "sourcehut"; disabled = false; }]; general = { instance_name = "NatFlix Search"; enable_metrics = false; }; brand = { new_issue_url = ""; docs_url = ""; public_instances = ""; wiki_url = ""; issue_url = ""; }; search = { safe_search = 0; autocomplete = "duckduckgo"; autocomplete_min = 2; default_lang = "en"; max_page = 0; }; server = { base_url = "https://searxng.\${EXTERNAL_DOMAIN}/"; image_proxy = true; http_protocol_version = "1.1"; method = "GET"; }; ui = { static_use_hash = true; infinite_scroll = true; default_theme = "simple"; theme_args = { simple_style = "dark"; }; }; enabled_plugins = [ "Hash plugin" "Search on category select" "Self Information" "Tracker URL remover" "Open Access DOI rewrite" "Vim-like hotkeys" ]; };
configFile = builtins.toFile "config.yaml" (builtins.toJSON configNix);
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
volumes = [
"${configFile}:/config/config.yaml:ro"
"/etc/localtime:/etc/localtime:ro"
];
environment = {
TZ = "${config.time.timeZone}";
SEARXNG_BASE_URL = "https://searxng.${config.mySystem.domain}/";
SEARXNG_URL = "https://searxng.${config.mySystem.domain}";
};
extraOptions = [
"--read-only"
"--tmpfs=/etc/searxng/"
"--cap-add=CHOWN"
"--cap-add=SETGID"
"--cap-add=SETUID"
"--cap-add=DAC_OVERRIDE"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.homepage.home = mkIf cfg.addToHomepage [
{
Searxng = {
icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Private meta search engine";
};
}
];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "30s";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
};
}

View file

@ -1,87 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "tautulli";
image = "ghcr.io/onedr0p/tautulli:2.13.4@sha256:633a57b2f8634feb67811064ec3fa52f40a70641be927fdfda6f5d91ebbd5d73";
user = "568"; #string
group = "568"; #string
port = 8181; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${appFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
volumes = [
"${appFolder}:/config:rw"
"${config.mySystem.nasFolder}/natflix:/media:rw"
"${config.mySystem.nasFolder}/backup/kubernetes/apps/tautulli:/config/backup:rw"
"/etc/localtime:/etc/localtime:ro"
];
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.media = mkIf cfg.addToHomepage [
{
Tautulli = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Plex Monitoring & Stats";
container = "${app}";
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,86 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
app = "whoogle";
image = "ghcr.io/benbusby/whoogle-search:0.8.4@sha256:93977c3aec8a039df94745a6e960d1b590a897e451b874c90ce484fbdbc3630f";
user = "927"; #string
group = "927"; #string
port = 5000; #int
cfg = config.mySystem.services.${app};
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
in
{
options.mySystem.services.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
virtualisation.oci-containers.containers.${app} = {
image = "${image}";
user = "${user}:${group}";
ports = [ (builtins.toString port) ]; # expose port
environment = {
TZ = "${config.time.timeZone}";
WHOOGLE_ALT_TW = "nitter.${config.networking.domain}";
WHOOGLE_ALT_YT = "invidious.${config.networking.domain}";
WHOOGLE_ALT_IG = "imginn.com";
WHOOGLE_ALT_RD = "redlib.${config.networking.domain}";
WHOOGLE_ALT_MD = "scribe.${config.networking.domain}";
WHOOGLE_ALT_TL = "";
WHOOGLE_ALT_IMG = "bibliogram.art";
WHOOGLE_ALT_IMDB = "";
WHOOGLE_ALT_WIKI = "";
WHOOGLE_ALT_QUORA = "";
WHOOGLE_CONFIG_ALTS = "1";
WHOOGLE_CONFIG_THEME = "system";
WHOOGLE_CONFIG_URL = "https://search.${config.networking.domain}";
WHOOGLE_CONFIG_GET_ONLY = "1";
WHOOGLE_CONFIG_COUNTRY = "AU";
WHOOGLE_CONFIG_VIEW_IMAGE = "1";
WHOOGLE_CONFIG_DISABLE = "1";
};
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."^~ /" = {
proxyPass = "http://${app}:${builtins.toString port}";
extraConfig = "resolver 10.88.0.1;";
};
};
mySystem.services.homepage.home = mkIf cfg.addToHomepage [
{
Whoogle = {
icon = "whooglesearch.png";
href = "https://${app}.${config.mySystem.domain}";
description = "Google frontend";
container = "${app}";
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "services";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
};
}

View file

@ -6,7 +6,6 @@ with lib;
./programs
./services
./de
./editor
./hardware
./containers
./lib.nix
@ -24,6 +23,11 @@ with lib;
description = "folder where nas mounts reside";
default = "/mnt/nas";
};
options.mySystem.nasAddress = mkOption {
type = types.str;
description = "NAS Address or name for the backup nas";
default = "10.1.1.13";
};
options.mySystem.domain = mkOption {
type = types.str;
description = "domain for hosted services";

View file

@ -1,6 +0,0 @@
{
imports = [
./vscodium.nix
];
}

View file

@ -1,156 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.editor.vscodium;
in
{
options.mySystem.editor.vscodium.enable = mkEnableOption "Vscodium";
config = mkIf cfg.enable {
# TODO add USER settings.json
# Enable vscode & addons
environment.systemPackages = with pkgs; [
(vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions = with vscode-extensions;
[
bbenoist.nix
mkhl.direnv
streetsidesoftware.code-spell-checker
oderwat.indent-rainbow
]
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "prettier-vscode";
publisher = "esbenp";
version = "10.1.0";
sha256 = "01s0vi2h917mqfpdrhqhp2ijwkibw95yk2js0l587wvajbbry2s9";
}
{
name = "vscode-docker";
publisher = "ms-azuretools";
version = "1.28.0";
sha256 = "0nmc3pdgxpmr6k2ksdczkv9bbwszncfczik0xjympqnd2k0ra9h0";
}
{
name = "gitlens";
publisher = "eamodio";
version = "14.7.0";
sha256 = "07f9fryaci8lsrdahgll5yhlzf5rhscpy1zd258hi211ymvkxlmy";
}
{
name = "remote-containers";
publisher = "ms-vscode-remote";
version = "0.327.0";
sha256 = "0asswm55bx5gpz08cgpmgfvnb0494irj0gsvzx5nwknqfzpj07lz";
}
{
name = "remote-ssh";
publisher = "ms-vscode-remote";
version = "0.107.1";
sha256 = "1q9xp8id9afhjx67zc7a61zb572f296apvdz305xd5v4brqd9xrf";
}
{
name = "vscode-yaml";
publisher = "redhat";
version = "1.14.0";
sha256 = "0pww9qndd2vsizsibjsvscz9fbfx8srrj67x4vhmwr581q674944";
}
{
name = "todo-tree";
publisher = "gruntfuggly";
version = "0.0.226";
sha256 = "0yrc9qbdk7zznd823bqs1g6n2i5xrda0f9a7349kknj9wp1mqgqn";
}
{
name = "path-autocomplete";
publisher = "ionutvmi";
version = "1.25.0";
sha256 = "0jjqh3p456p1aafw1gl6xgxw4cqqzs3hssr74mdsmh77bjizcgcb";
}
{
name = "even-better-toml";
publisher = "tamasfe";
version = "0.19.2";
sha256 = "0q9z98i446cc8bw1h1mvrddn3dnpnm2gwmzwv2s3fxdni2ggma14";
}
{
name = "linter";
publisher = "fnando";
version = "0.0.19";
sha256 = "13bllbxd7sy4qlclh37qvvnjp1v13al11nskcf2a8pmnmj455v4g";
}
{
name = "catppuccin-vsc";
publisher = "catppuccin";
version = "3.11.0";
sha256 = "12bzx1pv9pxbm08dhvl8pskpz1vg2whxmasl0qk2x54swa2rhi4d";
}
{
name = "catppuccin-vsc-icons";
publisher = "catppuccin";
version = "1.8.0";
sha256 = "12sw9f00vnmppmvhwbamyjcap3acjs1f67mdmyv6ka52mav58z8z";
}
{
name = "nix-ide";
publisher = "jnoortheen";
version = "0.2.2";
sha256 = "1264027sjh9a112si0y0p3pk3y36shj5b4qkpsj207z7lbxqq0wg";
}
{
name = "vscode-swissknife";
publisher = "luisfontes19";
version = "1.8.1";
sha256 = "1rpk8zayzkn2kg4jjdd2fy6xl50kib71dqg73v46326cr4dwxa7c";
}
{
name = "pre-commit-helper";
publisher = "elagil";
version = "0.5.0";
sha256 = "05cs1ndnha9dgv1ys23z81ajk300wpixqmks0lfmrj1zwyjg2wlj";
}
{
name = "sops-edit";
publisher = "shipitsmarter";
version = "1.0.0";
sha256 = "0b2z9khiwrpf6gxdb9y315ayqkibvgixmvx82in5rlp8pndb6sq4";
}
{
name = "json5-for-vscode";
publisher = "tudoudou";
version = "0.0.3";
sha256 = "1d1c18mr91ll5fsp0l0aszyi7nx0ad352ssm0fm40z81m4dmzm0w";
}
];
})
];
};
}

View file

@ -32,7 +32,6 @@ with lib;
}
);
# build a restic restore set for both local and remote
lib.mySystem.mkRestic = options: (
let
@ -53,7 +52,6 @@ with lib;
#
${pkgs.restic}/bin/restic unlock --remove-all || true
'';
in
{
# local backup

View file

@ -17,9 +17,7 @@ in
type = lib.types.bool;
description = "If we want to add fish plugins";
default = true;
};
};
# Install fish systemwide

View file

@ -1,6 +1,6 @@
security:
acme:
env: ENC[AES256_GCM,data:ZdtHl/MTYH1Hiw5Euf6PudZi74rFapfjbUlgEpUXA+H1kbqhZ8SdxEad1Pp8bAhEMpjK72uIAwHtGzz3HgElp4g=,iv:I5q2Ntn7Fh34VQd6ALH8NjKJI21V+fGBdw9RIEd8ksg=,tag:Y5mlPUq0QEAdXeU4Y4cheg==,type:str]
env: ENC[AES256_GCM,data:/exabYG1GvSCxe+TBeECudCN6DQLVBrifa9509skrNRYBsbm1UJRK+WxO0xcrAQkcb1Lse4WE95ueQurSFaY81w=,iv:oD2zcXbO12TlOeH0xLYsaHWw4PVjMHtbVm1LAWp89oo=,tag:dwGBevRXV1B4n/5Sveq5cg==,type:str]
sops:
kms: []
gcp_kms: []
@ -10,41 +10,41 @@ sops:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6WjhEaW54SEpGRGgwT0ly
REVkS2xvOGxhT1puRm5Gc0N1Y1FHWko1ekcwCml5MHFWWG1qNjNZbkY1TldORFdm
YWRMTjJwODFYZFhXcHNxWUViNCtVcUEKLS0tIGlpdVdwc01XUmpsT0VFSWJXa01J
bHoxZnBPZFFjQ0FCdWJrVGwzcEEzakEKNLWXfzWIQqaciDQ9ZQc3qnF9lnZew1D6
q3vHQJ6rEagGh/EsHzdDzo8y5NOj7L5e+Igi9rwtoS7+Xle55i3T+Q==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGVEVHekhud2xUclpURFZB
bzgrSkh2TWFibndHcTBpb3AySjRnUWliYzJBCmlROE83ZmJNbWpLaTExOUNwTmZw
dElIUThUQVo3MjlobjVrdFMrZUJHM1EKLS0tIGVlcU16Vm12eERKN1o1Ym1yRnJB
UkR2YUlLSnBWT0QrWTJuS0hRMnhBM2MKBaaD1gtd52RwKKPf7Yi7fhVEot6kIhAg
oaS589WtWIiIiEs/Fde8QfOEJ4aydhuyfVFGxsJkb8a5QGkjKP4Faw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEbUUzc1BHbWkxQlJqcDZs
aVhrYkdzM054R3hkT2g4Tm90WTNseEdlR21VCkF3NkJqSVIrYzJZUHVNNVJncEla
RnVDcG1OTWlQa2l4dEVhdEQ3dWRTa3MKLS0tIEpnQ3pqb090N0Jta0QzdEhrNUFy
eU9iZ0xzSUcrVG1VV3BQbnUxSll1ZWsKeSVfkJgoPnSiW0rguTwUFvbYdA2LETIR
OePUhnczLMJL6Qj+uolCJB5cedLPpmOuPILKU1BI0eZEmH8HsarCdQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiSEwyT21iZHl2cEtKZTRG
RGwwclFtTnNkK2c0U2U0U2NTWTkrckllbHhrCkprUTRxcFJnT3hTS3VuUjZXQUti
MDNWZGMrSmFDL2svaTJDZlEwcFpEeEUKLS0tIEVBMDlxZmVEU0UreS9KZnNodWcy
bUF2WVRySUd6NDJpbFRiYWszVlFYeGMK7Cl76mjrhdMNKy3SXQ4KqpUJl/P9peJc
O+EZ0Q1m0tZrShg1soqdMb1p/00ubvy+Rvxx5Tq0jsIF/Lq0Y3Q3CA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBudk1BWGVWY1IwSXhOZVNX
bHFQQ0pYaWo3R3B1bXFpbndRMTdBRHdndlNvClJSTjN6WTQ4b2V2NHdISXVTMDZj
MkFrQnhMUmIxWnJGZjFRT3VDeWVZQW8KLS0tIENlTUM1TEdnOEh6UFVjSWREYW5q
THhhdG5oYm96QlUwZW42YUJDeDdTbW8KNRwQ/ENQPgeJiXNggFxcgkymhVQy66TO
IRzxYmmo/MlBhDWQlk0EBFHYudmC8lF7n/pTvM8pz6V/5tc0Y1R9ow==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5U0cyRlFDaCsvSEZyeE1q
WXpUdU5teVpGT1J6dkJ3VHJudG5UaEIvMlYwCm8xcldxOTFEV3JJbUhYbHNjZjgw
T2tDZERTNnZtdVEvNWo5STZTdzZYbnMKLS0tIHpXQUREODAzOWIzcGVxZFJ1a2Rh
S2U3T2NUdkVKL3VhWGtRTXUrclJ3TnMKE+6waO9P3EWCGeBRmh3OH689ttLU0F0G
hEeBbwYSXfrXtHGSEwwNo++5vP1UVA7KUvLTF2G3mM2nhztJwacWtg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvWDgwSXowMG5pM2dzbDJJ
clNFM2UvcVZWT0o4UVZQdnlxc25BeXR4V1hjClVzZHlXaHQvN0NiT0JoWG9EWmRz
VDAyTkxod0FGVENOZndMTE9aZnM1UmcKLS0tIHAzWFRoZVdXNnIya0gyMFVXa1Va
SUtQblFtK2RSR1F6WFphUWlXRmJCeDgKbvve6CId6RF/F90Px5sl6FdJH6VhLR4w
K52iqxq1or/YKUn69dC9l21UwW2u1dJ7g9lTXcRll/clmh8LtDXZXw==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsSEREWEtSWTFUN1l3Uktp
YlJCNUZEMnBJL0xQc21VenBkVTgrcVBDQlJFCm51QkhVK2J4ODNQN3AyZ2V4dnQw
SVI2blo4SzdSYVdpeDluSFJ1YjFscXMKLS0tIEFMQXAyMGc2MHdMYjkxeHZOWHJ3
TnJ6dFBkUGpXMTBjRU5MMVJGTWZmd2sKh83VVst9g3e9lbx2v3b46X23HHtQAeS/
//oLEkBDuk5yqnNFtbcSGsWI9DBh9mD87bupw0Hz7GXTC/5LkApTkQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-13T03:24:35Z"
mac: ENC[AES256_GCM,data:Gz8uMG1pYseVsD1ooCuT48euPjed47su97ycdtKFsy8r3fLRvXUIfP8YPxSJ/OPGPm0yXBoNGRCovoey1N3B8NQXqWmQ78pmHIEVN6EqM8DvKLUn3a4XR52g0mURGqgFqJJXJCxn/UN4SMs1Kbl3Ahc9cXf17J1MoScVRqhpDWE=,iv:xYX7OUtaKDwjRohYN3q0mdrFfjop3XtzxAjQrMFrydk=,tag:sawX4x4KFzHJoPAeE18dag==,type:str]
lastmodified: "2024-05-18T16:39:41Z"
mac: ENC[AES256_GCM,data:tiHQmGUiTuM6aH5Vf9abJUIPDlQ73vmXHCNvkoBHanX7k9ScDxpByqgnDaIR2Tue4SusVVgXFpAlSda9fTT/bSgLUA1+0Qxo4YDLRz5I0pp4sCXAGVELHguADKwAbv+AyT7x4idzecLZ532RGqKkLWHljfOzHtAAlA8FBHH3ylk=,iv:iHlFeshdBreirhJGCBYUucUkz0oEbxYLo6dIeab73e0=,tag:ZeUXSWla9hDldeoqFIw+/g==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,213 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.adguardhome;
app = "adguard-home";
yaml_schema_version = 24;
port = 53;
port_webui = 3000;
adguardUser = "adguardhome";
in
{
options.mySystem.services.adguardhome = {
enable = mkEnableOption "Adguard Home";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
openFirewall = mkEnableOption "Open firewall for ${app}" // {
default = true;
};
};
config = mkIf cfg.enable {
# Warn if backups are disable and machine isnt a dev box
warnings = mkIf (yaml_schema_version != pkgs.adguardhome.schema_version) [ "WARNING: Adguard upstream YAML schema is version ${builtins.toString pkgs.adguardhome.schema_version}, this config is set to ${builtins.toString config.services.adguardhome.settings.schema_version}" ];
sops.secrets."services/adguardhome/password" = {
sopsFile = ./secrets.sops.yaml;
owner = adguardUser;
restartUnits = [ "adguardhome.service" ];
};
services.adguardhome = {
enable = true;
mutableSettings = false;
settings = {
bind_host = "0.0.0.0";
bind_port = port_webui;
schema_version = yaml_schema_version; # Just to be cautious, defualt is pkgs.adguardhome.schema_version.
users = [{
name = "admin";
password = "ADGUARDPASS"; # placeholder
}];
auth_attempts = 3;
block_auth_min = 3600;
dns = {
# dns server bind deets
bind_host = "127.0.0.1";
inherit port;
protection_enabled = true;
filtering_enabled = true;
# bootstrap DNS - used for resolving upstream dns deets
bootstrap_dns = [
# quad9
"9.9.9.10"
"149.112.112.10"
"2620:fe::10"
"2620:fe::fe:10"
# cloudflare
"1.1.1.1"
"2606:4700:4700::1111"
];
# upstream DNS
upstream_dns = [
# split brain dns - forward to local powerdns
"[/trux.dev/]127.0.0.1:5353"
# resolve fqdn for local ip's
"[/l.voltaicforge.com/]10.8.10.1"
# reverse dns setup
"[/in-addr.arpa/]10.8.10.1" # reverse dns lookup to UDMP
"[/ip6.arpa/]10.8.10.1" # reverse dns lookup to UDMP
# primary dns - quad9
"https://dns10.quad9.net/dns-query"
];
upstream_mode = "load_balance";
# fallback dns - cloudflare and mullvad
fallback_dns = [
"https://dns.cloudflare.com/dns-query"
"https://doh.mullvad.net/dns-query"
];
# resolving local addresses
local_ptr_upstreams = [ "10.8.10.1" ]; # UDMP router
use_private_ptr_resolvers = true;
# security
enable_dnssec = true;
# local cache settings
cache_size = 100000000; # 100MB - unnessecary but hey
cache_ttl_min = 60;
cache_optimistic = true;
theme = "auto";
};
filters =
let
urls = [
{ name = "AdGuard DNS filter"; url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; }
{ name = "AdAway Default Blocklist"; url = "https://adaway.org/hosts.txt"; }
{ name = "Big OSID"; url = "https://big.oisd.nl"; }
{ name = "1Hosts Lite"; url = "https://o0.pages.dev/Lite/adblock.txt"; }
{ name = "hagezi multi pro"; url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.txt"; }
{ name = "osint"; url = "https://osint.digitalside.it/Threat-Intel/lists/latestdomains.txt"; }
{ name = "phishing army"; url = "https://phishing.army/download/phishing_army_blocklist_extended.txt"; }
{ name = "notrack malware"; url = "https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-malware.txt"; }
{ name = "EasyPrivacy"; url = "https://v.firebog.net/hosts/Easyprivacy.txt"; }
];
buildList = id: url: {
enabled = true;
inherit id;
inherit (url) name;
inherit (url) url;
};
in
lib.imap1 buildList urls;
};
};
# add user, needed to access the secret
users.users.${adguardUser} = {
isSystemUser = true;
group = adguardUser;
};
users.groups.${adguardUser} = { };
# insert password before service starts
# password in sops is unencrypted, so we bcrypt it
# and insert it as per config requirements
systemd.services.adguardhome = {
preStart = lib.mkAfter ''
HASH=$(cat ${config.sops.secrets."services/adguardhome/password".path} | ${pkgs.apacheHttpd}/bin/htpasswd -niB "" | cut -c 2-)
${pkgs.gnused}/bin/sed -i "s,ADGUARDPASS,$HASH," "$STATE_DIRECTORY/AdGuardHome.yaml"
'';
serviceConfig.User = adguardUser;
};
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ port port_webui ];
allowedUDPPorts = [ port port_webui ];
};
mySystem.services.gatus.monitors = [
{
name = "${config.networking.hostName} external dns";
group = "dns";
url = "${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port}";
dns = {
query-name = "cloudflare.com";
query-type = "A";
};
interval = "1m";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "${config.networking.hostName} internal dns";
group = "dns";
url = "${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port}";
dns = {
query-name = "unifi.${config.mySystem.internalDomain}";
query-type = "A";
};
interval = "1m";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
];
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
"Adguard ${config.networking.hostName}" = {
icon = "${app}.svg";
href = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port_webui}";
description = "DNS Ad blocking";
container = "Infrastructure";
widget =
{
type = "adguard";
url = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port_webui}";
username = "admin";
password = "{{HOMEPAGE_VAR_ADGUARDHOME_PASS}}";
};
};
}
];
};
}

View file

@ -1,78 +0,0 @@
services:
adguardhome:
password: ENC[AES256_GCM,data:LO+CWyPEYKA=,iv:of7rfa2afrK+/zO2fxpMgEFCed2FzHr3g3XvsW7MEqE=,tag:rmyDo8/MIUtBHLPCHjwoOA==,type:str]
env: ENC[AES256_GCM,data:U8lindfbchCpD3DYkkwqMTcvKM/DWzbyAKvzOwx+FIfVl6OtMak=,iv:hRP5k9yipMVYEQB+lz2jauf59aSf3+or6YbRM7p2isc=,tag:fRz4aNoCHiwsCACN9+/CZg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpaUo2NmF0VGhzQm9ycDND
RnNNUGpsN3dWS05YRDM0YU9jQStEQWNrYUdrCkRQVDA3TjNFS3IwTWE0VkZISE5X
MHN5aElJMFYzRHB1K1dsUVhEVDFxVmcKLS0tIEh0c2UvT2hCK0wvdHorV0dUV0JT
REtTYXJnS2ZhNk9uaGhNSGJEQzV2S1EKWSmmm6xP7eplu8rAc6YXsXvj+lV96umT
MOs0/6oR+rKOTknEEUTVeQl6Fe9rtHS7UHFP7Mpk3vh647l9KOFoZA==
-----END AGE ENCRYPTED FILE-----
- recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOdkp5M1VtM1ZvM0tIN3p6
WUs1a0xZYyswTlRoeFFlcTJFTWgrRVAvbEJZCnVPMTBRUTF4RFdYVk5yZ0NCMmJ1
Y21YLzVrZDd5Z1ZFOGpwNmFXSWp4Z2cKLS0tIFJPMVcyVXpoRGRzSTlvZGtwUFRt
VmhzMUczR2l3b0RPem9VNlhXaCtBaXcK6Ch7J/UnzQLggMTS+4eOmIZatAY8cmqF
9DKeRs5euytwEDJUrXFm8hCc4p/Lf/OH0f74coXtXmEV1ejoHklDNQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5SmFpWCtRZkNVNktFK0Fx
R05xT2NnU1d5RTgrTU81eDhwZDZtNkpyWVFBClRZRGNBaFg1WWhITncxL085clJ5
eDY2Q1kzWXlMdUZ5RUl5eklMY2dNN1UKLS0tIDVDYXY3VVl5MStlUFNTQU9xS1Ra
bWVqWmpobEExcWFOdVpxQnJNaThWV1kKuZLi1DntH94dLnZejAZbkwxHGb6mAhSU
UvdRVNOKB0+7vGMHRqI8XGBgrkDGe3eriya4tcHFA+hQlTqTPJsPPw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkZVdDM0tGZEZRcHlyNnJJ
SGh1VzBqRG1RNFFRaGtuSENCa3BrSTV0Y0JZCnJJbUhENFRoUW9JVjZSMmd2b25n
bDVCdFBWQThGWjFHeStGQ1JTVkVOSncKLS0tIGM3YmdvUndSS214bTZHd0FYZXFn
a1FZUTE0cmVFMEt3K1l1WDlkcHllYk0KEyDE20xEfXT2n8+SxZcwirfiRkk+VPrg
iJJO46gNjwN6pmLW6N9XavAV7TRqSX9nRRNslMNcmf/FXo1jgwDiEQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ekt5xz7u2xgdzgsrffhd9x22n80cn4thxd8zxjy2ey5vq3ca7gnqz25g5r
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2SVBzRkJvMVNsazM3MEEw
OS91V3NqeGI2dklEbVlKekM0WEZRTmEvRnl3CnI5N0NIMTBFNmxaMjZQYVZGSmFI
MG9wWGpMc3p0UmZtd0hOLzE5R09DVGsKLS0tIEZBWWVIb0twWHlSVHdJQWd2bWRs
dnlIOXhFc3VMQ29FeVdWL2xoYUpKa1kKd6tU03d/aop+Isl62DF2iorDOvGGqOob
u3JRXJYJsdEAzJb9hV1De4QGAm/pa8lsMFoG+3shIZOFo9ZG1Iu9sQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlWDcyb1lhNk1HR1BkOURl
L2M1ZDRpUEVRS0VSRXRDUXpiVjRCNWFQa2ljCmJMY2dvRVZZTTd6L2V1MlBydmF6
Vld6U2ppcWhXSGh2ZElRQWErS0JNK2cKLS0tICtFbVp5N0FKR2lwSXEwc0NVTldk
MFlsOTZZSGtlSGVhaVhtdWwyWUF4ZkEK5OEd2m61aTa8HvKEhK82rfnIs4aff6gk
Ls6g5vaV6g8oh60sunuVohf6E0Clnjf5T+l8emSy9a5dv6iQ5tkbfg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGSEh6VUc1UEhSUzNwQkcw
cnZnS214Ly9sN1hCTkVZYXdLTkUwR1kvb1Z3CnVKNS9CYitiYi81L09aV1RIb1hj
NUlmUUI1UWtac094dDJFNGVUWVpnek0KLS0tIGtxemxUMVFSMGVmYUFONlc0cFE4
L1dJbXJqVWxUNDR2dEI1YmVsRmVlZlUKpoRUvVf8IttYAyXdyYCKq3iAzS+nFXIS
8TGxzD1FHwOWEd7gEWVOvPFHiGYPuMbWSkt/iEuTfu06YFZ71n+O6g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-04-25T02:28:14Z"
mac: ENC[AES256_GCM,data:NcY2RQcEu4RtCPotGn075MxA1Kn5spd8EHHem/IKsA68LoMXz7XN1RtFIvbvBPUYSOof93l88pJNGnz9gdTqZSkWEG3zUgCUxXryjcFj5hBojW3nEYtXJRlpsK++VBJSa50rJ7+E1tB5cA/6MIbUpY7F6IUu0ye7hatwj5TZ0n0=,iv:M5pZaYBIg3mJGh0wQ48WEYFfDvjY9DKnEveQRbfMrao=,tag:DrLPUtiKtc3NPRsCE1sJCQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,221 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.blocky;
in
{
options.mySystem.services.blocky.enable = mkEnableOption "blocky";
config = mkIf cfg.enable {
services.blocky = {
enable = true;
settings = {
# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.)
blocking = {
# definition of blacklist groups. Can be external link (http/https) or local file
blackLists = {
ads = [
"https://blocklistproject.github.io/Lists/ads.txt"
];
malicious = [
"https://blocklistproject.github.io/Lists/adguard/malware-ags.txt"
];
adult = [
"https://blocklistproject.github.io/Lists/adguard/porn-ags.txt"
];
void = [ ];
};
# definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked
whiteLists.ads = [ ];
# definition: which groups should be applied for which client
clientGroupsBlock = {
# default will be used, if no special definition for a client name exists
default = [ "ads" "malicious" ];
# use client name (with wildcard support: * - sequence of any characters, [0-9] - range)
# or single ip address / client subnet as CIDR notation
# "foo*" = [ "ads" ];
"10.8.10.40/24" = [ "ads" "malicioous" "adult" ];
};
# which response will be sent, if query is blocked:
# zeroIp: 0.0.0.0 will be returned (default)
# nxDomain: return NXDOMAIN as return code
# comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page.
blockType = "zeroIp";
# optional: TTL for answers to blocked domains
# default: 6h
blockTTL = "6h";
loading = {
# optional: automatically list refresh period (in duration format). Default: 4h.
# Negative value -> deactivate automatically refresh.
# 0 value -> use default
refreshPeriod = "4h";
# optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking
strategy = "fast";
downloads = {
# optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections
timeout = "60s";
# optional: Number of download attempts.
attempts = 5;
# optional: Time between the download attempts. Default: 1s
cooldown = "1s";
};
};
};
# optional: use these DNS servers to resolve blacklist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
bootstrapDns = [
{
upstream = "https://one.one.one.one/dns-query";
ips = [ "1.1.1.1" "1.0.0.1" ];
}
{
upstream = "https://dns.quad9.net/dns-query";
ips = [ "9.9.9.9" "149.112.112.112" ];
}
];
# optional: configuration for caching of DNS responses
caching = {
# duration how long a response must be cached (min value).
# If <=0, use response's TTL, if >0 use this value, if TTL is smaller
# Default: 0
minTime = "0m";
# duration how long a response must be cached (max value).
# If <0, do not cache responses
# If 0, use TTL
# If > 0, use this value, if TTL is greater
# Default: 0
maxTime = "0m";
# Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM.
# Default (0): unlimited
maxItemsCount = 0;
# if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window)
# this improves the response time for often used queries, but significantly increases external traffic
# default: false
prefetching = true;
# prefetch track time window (in duration format)
# default: 120
prefetchExpires = "2h";
# name queries threshold for prefetch
# default: 5
prefetchThreshold = 5;
# Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM.
# Default (0): unlimited
prefetchMaxItemsCount = 0;
# Time how long negative results (NXDOMAIN response or empty result) are cached. A value of -1 will disable caching for negative results.
# Default: 30m
cacheTimeNegative = "90m";
};
# optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists.
# accepted: dual, v4, v6
# default: dual
connectIPVersion = "v4";
# optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma
# example: query "printer.local" or "my.printer.local" will return 192.168.178.3
customDNS = {
customTTL = "1h";
# optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined).
# if false, queries with unmapped types will be forwarded to the upstream resolver
filterUnmappedTypes = false;
# optional: replace domain in the query with other domain before resolver lookup in the mapping
# mapping = [ ];
};
# conditional = {
# fallbackUpstream = false;
# mapping = {
# "trux.dev" = "127.0.0.1:5353";
# # resolve fqdn for local ip's
# "l.voltaicforge.com" = "10.8.10.1";
# # reverse dns setup
# "in-addr.arpa" = "10.8.10.1"; # reverse dns lookup to UDMP
# "ip6.arpa" = "10.8.10.1"; # reverse dns lookup to UDMP
# };
# };
# optional: drop all queries with following query types. Default: empty
filtering.queryTypes = [ "AAAA" ];
# optional: logging configuration
log = {
# optional: Log level (one from debug, info, warn, error). Default: info
level = "info";
# optional: Log format (text or json). Default: text
format = "text";
# optional: log timestamps. Default: true
timestamp = true;
# optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false
privacy = false;
};
# optional: Minimal TLS version that the DoH and DoT server will use
minTlsServeVersion = "1.2";
# if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated
#certFile: server.crt
#keyFile: server.key
# optional: ports configuration
ports = {
# optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, "127.0.0.1:5353,[::1]:5353"
dns = 53;
# optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853
tls = 853;
# optional: Port(s) and optional bind ip address(es) to serve HTTPS used for prometheus metrics, pprof, REST API, DoH... If you wish to specify a specific IP, you can do so such as 192.168.0.1:443. Example: 443, :443, 127.0.0.1:443,[::1]:443
https = 8443;
# optional: Port(s) and optional bind ip address(es) to serve HTTP used for prometheus metrics, pprof, REST API, DoH... If you wish to specify a specific IP, you can do so such as 192.168.0.1:4000. Example: 4000, :4000, 127.0.0.1:4000,[::1]:4000
http = 4000;
};
# optional: configuration for prometheus metrics endpoint
prometheus = {
# enabled if true
enable = true;
# url path, optional (default '/metrics')
path = "/metrics";
};
# optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false
startVerifyUpstream = true;
upstreams = {
groups = {
# these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query
# format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh))
# this configuration is mandatory, please define at least one external DNS resolver
default = [
"https://dns10.quad9.net/dns-query"
"https://dns.cloudflare.com/dns-query"
"https://doh.mullvad.net/dns-query"
];
# optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range)
# or single ip address / client subnet as CIDR notation
"10.8.50.1/24" = [ "https://cloudflare-dns.com/dns-query" ];
};
# Blocky supports different upstream strategies (default parallel_best) that determine how and to which upstream DNS servers requests are forwarded.
strategy = "parallel_best";
# optional: timeout to query the upstream resolver. Default: 2s
timeout = "2s";
};
};
};
};
}

View file

@ -1,138 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "calibre-web";
category = "services";
description = "Calibre web-server";
# image = "%{image}";
inherit (config.services.calibre-web) user;#string
inherit (config.services.calibre-web) group;#string
port = 8083; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backup = mkOption
{
type = lib.types.bool;
description = "Enable backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
users.users.jahanson.extraGroups = [ group ];
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
## service
services.calibre-web = {
enable = true;
listen.ip = "0.0.0.0";
listen.port = port;
options = {
calibreLibrary = "${config.mySystem.nasFolder}/natflix/books/";
};
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts.${url} = {
forceSSL = true;
useACMEHost = config.networking.domain;
locations."^~ /" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
};
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
warnings = [
(mkIf (!cfg.backup && config.mySystem.purpose != "Development")
"WARNING: Backups for ${app} are disabled!")
];
services.restic.backups = mkIf cfg.backup (config.lib.mySystem.mkRestic
{
inherit app user;
paths = [ appFolder ];
inherit appFolder;
});
};
}

View file

@ -1,51 +0,0 @@
system:
networking:
cloudflare-dyndns:
apiTokenFile: ENC[AES256_GCM,data:bNg/,iv:Zt4clxpz4+HLBZQtoPSHSOyfoeiY8WmIC0NK8KKpoZE=,tag:RbwizOVkM+cfXZHzP1PDzw==,type:int]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBbkxUU3FIQnJDNWxrYXNm
Q0dBQ1J2Z2hpK1JXZ1NhT2JyWkFTbVFyeG1FCk5YT2RkcDltaGxhUkwxV0xmTzVy
QzFvYzR1ZTRrdWJzOEIyVG1PMGVCd1UKLS0tIGwySFd2WUk5bHVEZUtXMVhxQUhV
V0U0b0lTT3VSdXBLK3JJNHI4N1J3K1kKR1WbRwnhAxjC95olt0Qn9fGrG7r0oCVf
Un0X4Stg1IXisiSoGb4soAPGDsFmF8fjVv8ThzjwHtXg+2dMOFjObA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXNWIwT09XNzhWc1Bza1Bp
WFRGVWpHOE9YYXJ1OEE0WEQzandxdExBcjJzCi9QaU9EZ3hSSHowREszYmlZRXhJ
TElFMjkwS01wNGs0U1JsYlRCV09sT0UKLS0tIDZhMmsvZUJxQWF5RGY3U0QzZUdr
YjdENFFNaGdKNVZ1c0lkS3NhQ1pBOUkKhKiTX7kMqg+Swm4nUfrTuVCX4yrKqsS8
dxvb47fns+UZ/ethNU9n38zmgFzpuceWIzslxa+uRNAtk/bfD75SBw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDVlBIYUVyWkprQll0a0dO
YmNyN1ZMcS9FSy9JSDBwWm1aZzVzQ3BUbXlzCitraGNNOElLSzdPMEtlRGNmbzNW
VWxkNVRnT09hWXhGcEdMN0E1cmkyRW8KLS0tIGFZeHRFMmkxZ2doOUg3Y0F6WTFM
ckdXWFdESG5CT0ZJNmcvOSthVTJHTGcK4igNpUBRHsbanKSwJOLPmLTC+sDEjJX4
fDwBCbALA9OzenUlfeOrnxDfWeB+Ww3PfF0eUUK8ojAXUhbIqaUnjg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnQzVHcFRBbkRHYlRhVWNB
dGpWeGhyK29MVzdWdEJRNTVoQ2hXN2h2Mmp3ClpnbDdscS9uZ0RwcVJSUDF2R2I3
dWhrTHFEWFNnbkRwV2lsVXdrSjZZdXMKLS0tIFNWZnZaMmpKZGk2SjNySit5YkM5
VDJSbFMySy9OS0pZMytqVE1GS3h1T28KJuQfwvcUqKS4qVRNEQQTcePdwuYc2sjY
0UY80I4ABFWiyAqwQ+PG7Kd33Z+gSuNJqlLyX2LyACOKVqyqNeR8Qg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:7ZPUQ3KwVRsrLoB+7/DS3iZE/FtJW7kHlJLmkpZfLts5K0IIrtgDv4r9SyiSdA/ejwYan3zPwRvtlsXN2FqU5uoFomL37UK6+TSFDjnJWIWNeOEbhGRZ3opZfw2NIMQoiGMHQRXzLQK4I+flzwce3KKQgtRpmlO+iXzm7LN3eLs=,iv:quon4A5FME1bftGbmifsD8fsRR72zpcwvL/UQu3gn6U=,tag:gCK1SWg35TPwPC/LgAPxrA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,44 +0,0 @@
{ lib
, config
, ...
}:
with lib;
let
cfg = config.mySystem.services.cfDdns;
in
{
options.mySystem.services.cfDdns.enable = mkEnableOption "Cloudflare ddns";
config = mkIf cfg.enable {
# Current nixpkgs cf-ddns only supports using a env file for the apitoken
# but not for domains, which makes them hard to find.
# To circumvent this, I put both in the 'apiTokenFile' var
# so my secret is:
# apiTokenFile: |-
# CLOUDFLARE_API_TOKEN=derp
# CLOUDFLARE_DOMAINS=derp.herp.xyz derp1.herp.xyz
# TODO add notifications on IP change
# init secret
sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".sopsFile = ./cloudflare-dyndns.sops.yaml;
# Restart when secret changes
sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".restartUnits = [ "cloudflare-dyndns.service" ];
networking.firewall = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 53 ];
};
# Cloudflare dynamic dns to keep my DNS records pointed at home
services.cloudflare-dyndns = {
enable = true;
ipv6 = false;
proxied = true;
apiTokenFile = config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".path;
domains = [ ];
};
};
}

View file

@ -18,24 +18,10 @@ in
# remove packagekit and selinux, don't work on NixOS
postBuild = ''
${old.postBuild}
rm -rf \
dist/packagekit \
dist/selinux
'';
});
};
config.environment = mkIf cfg.enable {
systemPackages = with pkgs;
[
# (mkIf config.virtualisation.podman.enable nur.repos.procyon.cockpit-podman) # TODO replace only if server runs pods
# nur.repos.dukzcry.cockpit-machines # TODO enable with virtualisation on server
# nur.repos.dukzcry.libvirt-dbus # TODO enable with virtualisation on server
# pkgs.virt-manager # TODO enable with virtualisation on server
];
};
}

View file

@ -1,33 +1,18 @@
{
imports = [
./monitoring.nix
./reboot-required-check.nix
./cloudflare-dyndns
./maddy
./dnscrypt-proxy2
./cockpit
./podman
./traefik
./nfs
./nix-serve
./forgejo
./glances
./syncthing
./restic
./powerdns
./adguardhome
./mosquitto
./zigbee2mqtt
./postgresql
./blocky
./openvscode-server
./grafana
./monitoring.nix
./nfs
./nginx
./nix-serve
./podman
./postgresql
./prometheus
./radicale
./node-red
./nginx
./miniflux
./calibre-web
./rss-bridge
./forgejo
./reboot-required-check.nix
./restic
];
}

View file

@ -1,52 +0,0 @@
{ lib
, config
, ...
}:
with lib;
let
cfg = config.mySystem.services.dnscrypt-proxy;
in
{
options.mySystem.services.dnscrypt-proxy.enable = mkEnableOption "Cloudflare ddns";
config = mkIf cfg.enable {
# Disable resolvd to ensure it doesnt re-write /etc/resolv.conf
services.resolved.enable = false;
# Fix this devices DNS resolv.conf else resolvd will point it to dnscrypt
# causing a risk of no dns if service fails.
networking = {
nameservers = [ "10.8.10.1" ]; # TODO make varible IP
firewall.allowedTCPPorts = [ 53 ];
firewall.allowedUDPPorts = [ 53 ];
dhcpcd.extraConfig = "nohook resolv.conf";
};
sops.secrets = {
# configure secret for forwarding rules
"system/networking/dnscrypt-proxy2/forwarding-rules".sopsFile = ./dnscrypt-proxy2.sops.yaml;
"system/networking/dnscrypt-proxy2/forwarding-rules".mode = "0444"; # This is world-readable but theres nothing security related in the file
# Restart dnscrypt when secret changes
"system/networking/dnscrypt-proxy2/forwarding-rules".restartUnits = [ "dnscrypt-proxy2.service" ];
};
services.dnscrypt-proxy2 = {
enable = true;
settings = {
require_dnssec = true;
forwarding_rules = config.sops.secrets."system/networking/dnscrypt-proxy2/forwarding-rules".path;
listen_addresses = [ "0.0.0.0:53" ];
server_names = [ "NextDNS" ];
static = {
"NextDNS" = {
stamp = "sdns://AgEAAAAAAAAAAAAOZG5zLm5leHRkbnMuaW8HL2Y2ZmUzNQ";
};
};
};
};
};
}

View file

@ -1,51 +0,0 @@
system:
networking:
dnscrypt-proxy2:
forwarding-rules: ENC[AES256_GCM,data:7HwvXgs=,iv:Y+1VqcRn6lxcahN1gitJrhHvG5mSj2qBFlHOmbPV4Ns=,tag:CROQyeTRCynSIE3dJ2vVzg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTZ2piaVYySmsrOU9sbnI2
Q2xmR3V2Zk01UHRMNjN6Q2R5MUhEWGEvS1JRCllXRkorY3k2MzJ3QXpOV2JpaG8v
MWFKWlVkS2Z2RFpzMlpCaVN0TkhvSDQKLS0tIFAvZExaQjZBQXZwY1dqQWhLc25P
RERwOTQwYThMUHkzK24rc1dTcW5FcFUKi3iVa5lHCFIYeel3DH46WWRVhkYOEKw2
/kXqJ+aH4ul/e1xIsGBJWdKTg8V0K5JA454hw4WyofvhcdaZdjEqyw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkb3FlSFdQZEMzN1BuVEd5
WHkxUk5ETGpDeHlLeUorVTg3Z3ZqWHJ5SHdzCkpJY0lqMGN6RC84MGZzQnU3b3Ft
NGlMUUF4eDhvQ0JodGVEbHkxUjFINU0KLS0tIHNObkdLZnVZMmhWdHdkVGlEWlVT
N3U1STJaZEQrN1Y0SFRaWDlrSDFvdDAKmIrWErhAnTivaXVCrMpNvgUaxLIf5Azg
vjK15Olgd0lxHi41f/zAoOdv5P/BWss0Pc2lk0Qkspl/GhTAmTQN9w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCMGtrL2ZreFFRQ3ZHZ09y
UXM3RGFwMkdDWFlsWGY5Q29FUmlEUnZjZjJjCmJpZEJka25OQmJZdlRPZjFJZkh4
NERwOGhtMkJaTXZ0T1ppZlVVOWNERDgKLS0tIHVpUFFvU2plY2ZFVzZIUUFtN3hr
Q3ZEcmd2ZS9tOHZVQmdmTnVsV3dnbVkKz8fc2zwSrQ03WcppCGNnFYheL2udwHVj
qiIrI9hwKwp9s7hU2leUXWsd5z6A9oPelnr7TuQ+nGy3XHicEsjY5g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrbzVsQSs2Zm0vcEVybk1n
aUs2NmlOSSs1NHhwblFQOXErTFh2ekxIQ0hzCjd1S3h5a1hrL0V5dkZMaURrR1ZC
VmcrV1MwSU4yQlZiNXdWbTVCUkc4cXMKLS0tIEI5bW41Z1ErQWUrOW50VkFWeVRU
a1NFWTJvNTNuYXVYVkRhaHZCRmRyVU0KrKR67gl5OrLWLA5OlseCZeU+aNh8YtM4
psiAFihucI0f7A68J1xx3idBHa5iblBKrQAvdGkKMfR76gsn6XbM5Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:GGQuROg9LD0nbQSOd0d//JzSq5C6i3lo3memU6p4PMnCsODt0CxW6Srpb70uc4zHL+k1iuHvY1vDLwPW2/u4dcNZcDA4LLlf9BE3pRmrpzzXBfxguqlWuMk68tBNtLyXgpcTT/AN1OhBWS43GMwFUGEmF9jPc0XyQFfPT5sTYHk=,iv:9NtAWjPZW5Jg4UaBA6W95GJdkJ3evqAYwlPE2nNFd8A=,tag:0bGyF/kVUKXqswumE7kQSg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,7 +1,7 @@
services:
forgejo:
smtp:
password: ENC[AES256_GCM,data:WL+v0tKArR90bzbZ04lL6ODADSMXGHAEYAnNrhdgCShEcNjUwJXVHV8bsOIdiAsXoic=,iv:+KPPzcHrHPee2EhQCQzGsCNzLQa9t2MCdXHF3O8zZ+M=,tag:FuxrUg1/qS0WvD222wbfkw==,type:str]
password: ENC[AES256_GCM,data:p5iDVW+V0aIlj9RTHpMgko/1ahVkiHXafgm2u2g3TTrYFORBqCJqv+lCSSm4mGIabn4=,iv:GIx/dnn1y6Is6uzKEkmo326AUSS+I5RnLsV2duKHPBo=,tag:7R4222rGEsK+egunnB+llg==,type:str]
sops:
kms: []
gcp_kms: []
@ -11,41 +11,41 @@ sops:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByQmVLNjhPNThZa3dLd3ha
a0VCa1JDaGJXLzQwck1Ga2wvVWU0K1BCbkVRCjdlL3B0cUZVZEtFalFkb2lTWktL
cGZGcjR1KzVEYzZKakZHMnlBR0FvM2MKLS0tIHpRZm5nbGpVZmVpVVkrZVVSKzlk
ZUx0c29QMWpTRHJ0U3B1V2lkdEJvUk0KVK8GKsSl8uXhw8zbxpW4An/E7UI8yW6u
0MELMJtmskLQnCUKKbeE8nAHW2MMGt6schoXwqsAEkspeaf+AC2G1A==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVOU9SMEZvQUxhZWU2dzJ0
Z1ZUODd0R2Rtb2lmaHhweC9Tb0J2anJuRno4Cis5UGZHc3pobkQ2OUJwSy9tV1RF
SmNvUi9Xek9oVFdPdzZQUnlJeWtBSEEKLS0tIFpoWTZOYlFOK2p4bTFaUVhGV1hz
dlpWOWhLT2VtYXdDQjJlWnh4T05TT3MKJtewm9QN1EfT8IQkkHdH0GGNDyg1wH6Z
Ja6lcZB580FPEHwoMC7cayQe5v82vbQsj6s8mOaUW9yRQLMQMkmOfA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0Mk1UVzJQM044aG9BRmg3
QnUrdURwNGhONUxnR2Jjbjc1TitWWXEvb2dBCmlGSVh0Y0VNcExUYk9ER3JsNUgx
d1BCQWI2L0I0TGZoYUdmamg0aTBVbjQKLS0tIE52elRkSjd3eUlWempGSFBvbHoy
U1hZT2FVeEtkSDUvUERRYWpyanI2UUUKO7EHrVbhMFqZdwnIlK0Fnd5cLUVJ9Mhx
NRwYxneeBTHg2VV53n+n8mRhO0eQtOfNh6Mvc4eHC2eTBk/XlUynDg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6bUNpMWJ1YklkV1JPMnFi
S0tiajlKblV5aTU2djJaQjN0M1IwOU9pdTNRCnFycmQ5WHFadmxhZ1R6a1ZHYjlW
TjVCN2dUelc5Qkt5Y0ZtYUtNRHN0WTAKLS0tIDFKSUE2YzFmQzB1TjgrRDFEalJO
MDg0bU9NS3VObVVYNDAvY1JIRU5xZEEKSWzp9smLNYypodRIh49XPBxS536XtFWf
kJWaLiUfULifcN46F8Tyts9dGHXx/bOgM5rCFAqtqTL7EaJbam13pw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRZWtMQVhOTTJxM1dYYW5w
aFViZWU2KzR2RnpDZEdDbk5nU1loQ1F0cVdnCjlPb0VtNFYvQzBiNDZUaTROOHRO
a3ZlaFlGblhnR1hRK3lRQ05mR0lJYzQKLS0tIFovSzEyNXhrcC9iRjAyVlZBWXIy
UWZBeXIrR0tvaFBVTFhqblB0d2xTM0UKULrTgxENwhZvEpNS0/Puxoh2d8s2zNo4
EY+fkaR3dOGjnro+E6PYO7NydZOfc/rT/VUBAQi8Dl8DPlJHV4WOjw==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuQ09PSWwyY2tGZzdyOGxq
KzZuUW95Z2QzVXY4dk5tRGZ3MXMxNW9INXlRCmkra2t2UUMwWnBhM0VoTnpUaWIx
UW13a3VxZWJyL0ZDdk1IVXJNQitpblkKLS0tIGMwZHJqOGt4Y2FCUUUrc2tEQjY0
eWp3WmdOMUlTNVlUT3FMM0JCTnViQ28KE6rpeFodW4BAIDVdjpgPpRs26XgUya3b
Xbg6IuB90DvzNMKkoGB36Dh5cWUGFBsJ3QYopSDQGFbUepyDQa4Wvw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNaEpWdkk0eUpiT0duTjRS
aXEwZlh1dW5oQkNwMjRGbVNKeTRxanpneVdZCkZVTjJHblo0Ui8yYytKeDZHaFVn
eVAzeHpxck9VN0pDVnIyb3A3VGdxY2cKLS0tIGRiNVprcHFqVUpJeFJHNklkT3JR
azV4ajZHUXFnY1VHS0JzaHM1aUtySHcKWw3FRCjkKm99+Rw7uL+550go0EoKJdKY
6tBW4vsh0+a3WBd/cNXwHVt8R3UscZ+MOwgSKyHDA62slqblH+G81Q==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6VG9uejd2YTZ4c1p3akFZ
dUtEbXk3S1UzeEhLeld4VXVLK1dVKytlOEc4ClFwbVVUUG9SbzB2bDZwRHA2cE4y
STFLOWR3S0YrQ1FBbjJDV3o1aW1rNjgKLS0tIDlnQkZhRlpXanY5TzViVzdTNGpo
NDhZZ24zWmwwNVE4VDM0bllyUkdxVncKdyYx4r4ERRy2lz7b2oK4JvzF1RnIJ/mV
neTz0N1LSdmTUAOUtRT7D73tR6HhBZQNxH4LIsYiRllto46mEamx7g==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-12T03:37:15Z"
mac: ENC[AES256_GCM,data:OM7jU2HfvOtNDvK4C5FE567dobZxhBdCDu5KSyBgGfzgFi1tSX0F4YoRZhspmfQKOeT/3+vLj1bfqDIkv2krDeZOnxw8vns7qgnTgR2tOn15bQmS8mIkSyk5WWdS1tbHfk1v+vF8T6lsl78G4nDSU/Q9DyFFdgmQUDDzlwW5vAs=,iv:tZgzqxwPqdDpQVkC/9598ixEzUNES5YMNfTwGUOEErQ=,tag:2w3/EftLvS/a2wl8ug6t3Q==,type:str]
lastmodified: "2024-05-18T16:39:41Z"
mac: ENC[AES256_GCM,data:TQ019mze1TDfHM3unUvhLzQOdPVhZ0lIw+CbcuSGIqpjITr7nGVRYtPMvHtY9taxaAQgpdJghOaP9MS/YR6KT9II54qYtel944rmOHxOIpB8Oy/mRHBJvx1JhQxHzxPx6hLsLxNagSbgIpyiNGwMiR2gedBLPI/BBNcPGESiMTA=,iv:m4UnG4p0eWzRmspSU/RL4HSeq3Fr5t+9FnNMxgCMOJE=,tag:w2aJxYjVoEHlaQAT+VAa7g==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -79,16 +79,5 @@ with lib;
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
"Glances ${config.networking.hostName}" = {
icon = "${app}.svg";
href = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:61208";
description = "System Monitoring";
container = "Infrastructure";
};
}
];
};
}

View file

@ -28,12 +28,6 @@ in
description = "Enable gatus monitoring";
default = true;
};
# prometheus = mkOption
# {
# type = lib.types.bool;
# description = "Enable prometheus scraping";
# default = true;
# };
addToDNS = mkOption
{
type = lib.types.bool;
@ -58,14 +52,6 @@ in
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
users.users.jahanson.extraGroups = [ group ];
## service
@ -76,17 +62,6 @@ in
addr = "127.0.0.1";
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{

View file

@ -1,148 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "%{app}";
category = "%{cat}";
description = "%{description}";
image = "%{image}";
user = "%{user kah}"; #string
group = "%{group kah}"; #string
port = 1234; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backup = mkOption
{
type = lib.types.bool;
description = "Enable backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
users.users.jahanson.extraGroups = [ group ];
# Folder perms - only for containers
# systemd.tmpfiles.rules = [
# "d ${persistentFolder}/ 0750 ${user} ${group} -"
# ];
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
## service
# services.test= {
# enable = true;
# };
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts.${url} = {
forceSSL = true;
useACMEHost = config.networking.domain;
locations."^~ /" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
};
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
warnings = [
(mkIf (!cfg.backup && config.mySystem.purpose != "Development")
"WARNING: Backups for ${app} are disabled!")
];
services.restic.backups = mkIf cfg.backup (config.lib.mySystem.mkRestic
{
inherit app user;
paths = [ appFolder ];
inherit appFolder;
});
# services.postgresqlBackup = {
# databases = [ app ];
# };
};
}

View file

@ -1,31 +0,0 @@
{ lib
, config
, ...
}:
with lib;
let
cfg = config.mySystem.services.maddy;
in
{
options.mySystem.services.maddy.enable = mkEnableOption "Maddy SMTP Client (Relay)";
config = mkIf cfg.enable {
sops.secrets."system/mail/maddy/envFile" = {
sopsFile = ./maddy.sops.yaml;
owner = "maddy";
group = "maddy";
};
sops.secrets."system/mail/maddy/envFile".restartUnits = [ "maddy.service" ];
services.maddy = {
enable = true;
openFirewall = true;
secrets = [ config.sops.secrets."system/mail/maddy/envFile".path ];
config = builtins.readFile ./maddy.conf;
};
};
}

View file

@ -1,30 +0,0 @@
state_dir /dev/shm/maddy/state
runtime_dir /dev/shm/maddy/run
openmetrics tcp://0.0.0.0:9749 { }
smtp tcp://0.0.0.0:2525 {
debug {env:DEBUG}
io_debug {env:DEBUG}
source {env:SMTP_DOMAIN} {
deliver_to &remote_queue
}
default_source {
reject
}
}
target.queue remote_queue {
debug {env:DEBUG}
target &remote_smtp
}
target.smtp remote_smtp {
debug {env:DEBUG}
attempt_starttls yes
require_tls yes
auth plain {env:SMTP_USERNAME} {env:SMTP_PASSWORD}
targets tls://{env:SMTP_SERVER}:{env:SMTP_PORT}
}

View file

@ -1,51 +0,0 @@
system:
mail:
maddy:
envFile: ENC[AES256_GCM,data:TGLFJJWixtAVaSJuU42prg==,iv:rmwPfjW/2ALMbsJyepq23VXcLHrBp5ZWlxGIEh7uOO4=,tag:a/qKkPBCl3ewABlJv81lfw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiUTAwMEU0SGw0Q1lpOXJF
TnZGVzhINUlSTlFVcU8vcXl6czhrODJ0Q3c4CkNnVEwyb1AwanNzMEhvRmFaemUr
ZEFSOFgyU0RCM002Y0dPUjRRZXZZcDgKLS0tIHFJTnBaelMzV3Z2Ry8zNTYwWG5r
Y2xIWmc3QSsrVmZCdGhBbVREaFg4Qk0KjIE4soj0P7PZ/TsVSDCN05C43WFmmoFS
fn1dR0oIYygwGWz2poaI6Jb3Zm4cjEfhn27hcPDGp4kFIIz+97OXVA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ak8yckhRMm53bHpnQk5Y
K0hyaGFGcW5EUk9NUG1rS1BKczU5dVN0akhRCktmYlhvdnNPYnlWcVNUUklQNWpz
dFNZMDAyV2dwZUcrc2gzUW95aGZvalUKLS0tIE83TXFZRHNDNmZDZ2xwbm1jZnk3
WkdlVkt1ZzRuVTN6bFJuQ3I3WDdYOFEKo28KVA7f8acjrOp4sVWzgbBGUBzX6axI
8zNfrLtTz30Kx8rllMZ/t8x7jEGXDW4r2UQCgErt2s/Zdb6qNoBYqw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6bGRaWGxEMk9VYXJXYS93
TURXOVNxeWdkTkhMVUFLcERLWkx6YkNRd2drCnE0Z1RQYlQ4aTA0SVVFSTF2M3BW
NVVQdk9nMHNqL3hPTFNBSHdNczVNY00KLS0tIGVFdURIaitlYXR0TGh4UitYeGlM
a1NGWDdnOHlIc3JyTll4U0RoRk9xTUUKv0IVwG7nxvNfbJh6hmWpd+YtZw88NjFa
6m03PhSnjftVyi5ZkEEbAf4HsDgv+HW6w6Gmzlsf2FkTT5IDGgrquw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBTGFCWnNDTlIwTDJqNDc1
RVc4V3hiY2o1eEdsakwwcnp5Z1N1UGEyeENZCk1qUG1Db2FRTUx4ZTg2a0xtOTQw
UjBzSHFmaHJ3WlR0VGs0bzZpbWpOWDgKLS0tIC9hakJsYm9qZ2dSRzlGaXFpbURq
bW1OLzc3cnBXYkNuUFJNaERua0NTRzAKLX7YXGrrHfTtmHhNjEjd6N/7V9oic2/N
tXx274guzFcjfppTMGkvIV7yC7BleQMmbzlEVx6JKflUWVoQnNmYNw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:H+XTxzT6l3fmke+JO0y8OedKltDVETJsd4trm11/UIPEB57GhY80P34rnyc2Skz6DhV9a+rqkIq1mXlOv0zMhpobhb/9Gov6Hc+toK+8Km9J/ypikKen3m06unvV31j3Nw7coKPHEaK/XAyUx3un7+eaKGIkEG+xQnLm6cOLuEg=,iv:QxGs6OMvFxsnAXA1PN4ptZ4MT6S1ZAndQtXjpoz2Zhc=,tag:TVkg52QLS00alXy94wQ9JA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,180 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "miniflux";
category = "services";
description = "Minimalist feed reader";
# image = "%{image}";
user = app; #string
group = app; #string
port = 8072; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
databaseUrl = "user=miniflux host=/run/postgresql dbname=miniflux";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backup = mkOption
{
type = lib.types.bool;
description = "Enable backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
sops.secrets."${category}/${app}/env" = {
sopsFile = ./secrets.sops.yaml;
owner = user;
inherit group;
restartUnits = [ "${app}.service" ];
};
users.users.jahanson.extraGroups = [ group ];
users.users.miniflux = {
isSystemUser = true;
group = "miniflux";
};
users.groups.miniflux = { };
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
## service
services.miniflux = {
enable = true;
adminCredentialsFile = config.sops.secrets."${category}/${app}/env".path;
config = {
LISTEN_ADDR = "localhost:${builtins.toString port}";
DATABASE_URL = databaseUrl;
RUN_MIGRATIONS = "1";
CREATE_ADMIN = "1";
};
};
# automatically reset feed errors regular
# systemd.services.miniflux-reset-feed-errors = {
# description = "Miniflux reset feed errors";
# wantedBy = [ "multi-user.target" ];
# after = [ "network.target" "${app}.service" ];
# environment.DATABASE_URL = databaseUrl;
# startAt = "00/4:00"; # Every four hours.
# serviceConfig = {
# Type = "oneshot";
# DynamicUser = true;
# RuntimeDirectory = "miniflux"; # Creates /run/miniflux.
## EnvironmentFile = cfg.envFilePath;
# ExecStart = pkgs.writeShellScriptBin "miniflux-reset-feed-errors" ''
# ${cfg.package}/bin/miniflux -reset-feed-errors
# '';
# };
# };
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
# ensure postgresql setup
services.postgresql = {
ensureDatabases = [ app ];
ensureUsers = [{
name = app;
ensureDBOwnership = true;
}];
};
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts.${url} = {
forceSSL = true;
useACMEHost = config.networking.domain;
locations."^~ /" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
};
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
warnings = [
(mkIf (!cfg.backup && config.mySystem.purpose != "Development")
"WARNING: Backups for ${app} are disabled!")
];
# services.restic.backups = mkIf cfg.backup (config.lib.mySystem.mkRestic
# {
# inherit app user;
# paths = [ appFolder ];
# inherit appFolder;
# });
services.postgresqlBackup = mkIf cfg.backup {
databases = [ app ];
};
};
}

View file

@ -1,50 +0,0 @@
services:
miniflux:
env: ENC[AES256_GCM,data:T3nNmyoFmiTdJrgyfdwWfQ==,iv:b+80Yn6CSzXIwM3BbG9Jf6ZwPoCCdr4ykOspz9Fjaj0=,tag:jduWlAz8gT87NpR0KSv1ow==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDZ2N2WFF4VmkwL3I1cE80
dmxzRHZrZC9OelBsZ2N6WTZUKzhxNURlb1RjCjllTUdLTUgvOXBPclU5ZFQwYjdm
R2FkaUFGOWhtRjBxVExwMXdSUFl4NW8KLS0tIE5QV0gyNUUrTHlKVW5qWVI1NmNL
eVlsaGRCYlJnbnRrS05UYmJrSkNDUW8KxB6Jd4r0Bt4nLGjm4gP+wMHu9CvoHzqV
y/Y6NJWFqKIi30QcgW4jZ9E2Fu5I1dvAFmIKXNRM7bYI6lBz+JY5QA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSbDY3ZVRLMGowQzZPamlv
OWI2bitmcmIyOVJxQ3djM3hadHdRRXVrWmlZClpzdVM3U0g2YnZ4V2IrWDNpZVlT
WGg1V0lQR3Nwc2JpaVl3WG1zSmErTTgKLS0tIFo5VEZoZGtnSjhCMmlLd0tEREVM
ai9PMHlVaU5rWThzR0lJY3JGdTJwdUkKOkgwmFm4MussjOG26AmVibgrtj+hKAhl
o2FhSGw0BfI3K1X3tNg3RvEWQOXCyLFTl5w3gGeZ3fsNFwoaSpcSLg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3Z2krLzZVc0Q2b1Vpb1Mw
ME1RcGpGSzNNRkV3aGZwMEQyVGZHUDRwaTN3CjBqRFM2S3hIai80Z3BzWHdJdDZC
K29YZXZYL1IxVERKNW5qSjYvamxPNkEKLS0tIFd2RUl2MHBIZlJTTlFEQmlvU2Iw
YU9MbG5yRFJTSkwwR0ZwcDRVMDJIWUUKuCQIJkYZqj7yUvJTWzLyl+JhfUDUTmE5
j2z+EdRS0HQ+qpNNDJK0zc4uCUOXNmpsZgjUsdDfBvWmcnR02uXwXA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJbUN3eW4yWHZnQ1lRSklu
MVl2bWJKaHRrN1FCaDY2MHoxOW5QYVB0L21rCmVrTmF1YXdhSWJpaFJBMWR4SnZh
dC9UYWRnM0t6M09QdlRiK2Y4OUk2QkkKLS0tIEhIN1VJU3MrQlBHdVkwOUp3dEtC
MTdIRU9wNUg0dVV1L1AxTmVCL09QSW8KOXi+ysyVdBPX2//FhQi8GmtcVfxwlFGN
fgdzXO8PRNHyN2CYJMjQOzeV8es+s5xk9vS40Dl4u+8TFyIDJbn8nw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T02:52:42Z"
mac: ENC[AES256_GCM,data:jtjchjbuU2vXVBPGz7pyyMmP1R75Sf6LqepYqQaggZtXVjQL24pulPwViRIU4RsksHTdHNGzoDimWKF5xFrOb1FFeHglkfKOEBt8A/kYpttIOJcfTXxjFv44AldhUmFP2LaJKj2BRXpGiBtMBuB8kFUYqG2s80hDM27bMEEIrEQ=,iv:WZbTD6b5EC66XcyBSuQwsa+eVQmqYwuf8nARLlEFsfY=,tag:whk+hAZ9U+w3GUJmcambSQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,58 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.mosquitto;
# persistentFolder = "${config.mySystem.persistentFolder}/nixos/services/mosquitto/";
app = "mosquitto";
user = app;
group = app;
appFolder = config.services.mosquitto.dataDir;
in
{
options.mySystem.services.mosquitto.enable = mkEnableOption "mosquitto MQTT";
config = mkIf cfg.enable {
sops.secrets."services/mosquitto/mq/hashedPassword" = {
sopsFile = ./secrets.sops.yaml;
owner = app;
group = app;
restartUnits = [ "${app}.service" ];
};
services.mosquitto = {
enable = true;
# persistance for convienience on restarts
# but not backed up, there is no data
# that requires keeping in MQTT
settings = {
persistence_location = appFolder;
max_keepalive = 300;
};
listeners = [
{
users.mq = {
acl = [
"readwrite #"
];
hashedPasswordFile = config.sops.secrets."services/mosquitto/mq/hashedPassword".path;
};
}
];
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
users.users.jahanson.extraGroups = [ "mosquitto" ];
networking.firewall.allowedTCPPorts = [ 1883 ];
};
}

View file

@ -1,52 +0,0 @@
services:
mosquitto:
mq:
hashedPassword: ENC[AES256_GCM,data:ars=,iv:fpJQrFgs3Db0UGCDNqUqaUg8D6uBg0+W4Dkg2p1j2OI=,tag:D8yeAs+yQV67Un0yPeNzFA==,type:str]
plainPassword.yaml: ENC[AES256_GCM,data:OVZqyq/3OKf2mhrI0GtrHg==,iv:rUQuXRSGCRHk10DpA6KFLO4zP4BlroHSJyDT1oO8dvc=,tag:RtSvFJH2Evpn5QoyFaKHwQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXMXlGakdyNFVuemtWVUFF
ZDh5SVZ3aTBSWVdETE1oMFJ5Q0daMnZmQ2hJCndiQVBRM08vbnpXR3FQVlR5SWtm
ZWNMb2FqMEVWcGs2YTNFaUFOWW9idG8KLS0tIDNiQk1OV1lCUnd0eGNkT1VGNXFi
clZCVDY4L0lyUTg2NUpPdkx5NDgwYzgKOOdEdfLiP2V3txjKogJFVOD80y86bn6V
5KsWtsAd+QmtaBav+XHEFoWkcmBYXfKdl0Sg+VuLT+GiP+Dr9EIT1Q==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKVmZoc2lheCt0a0Y0S2ps
b3FURHNIdWlMWk5SdU54dW1lNmlPY2oxYlV3CmMxMzVHZVUrWTR6bm9XQWRjWUNw
V2NpSk9BNlJ2eGoraE00SytrZTdWdGMKLS0tIFliakZDeHRwNmpJM2lFVDNDYTNj
SXFxZk9CV1ZTSmFHTUIreDhlRmMzRmMKT1AJxxnKxNce1fa/Q1AsCWdpy86dYKpu
CPKBBYYl2w2pcs0Al+tZ+WtAdFtR5+YZ/6hWOTQT1bWMm7rQWMh6Kw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlUmdYdU8xTkNRUUVYVFpG
dGdyb214TSt2dGhlcFJFTE1lcWdXQ0lQVWswCmdFQjFadVNQU0YyK2YxQ3lQbjNh
d0xGWDRObFI3U3JvL0o0b3VsNFhXbXcKLS0tIGVHY0E1NHk5OTRkMkQ2OWVDcEMz
cWVlWUdtK09kQkUrZlFnTi90UEVyNkEKS5K98WlBImPdvn+zuOUvWeCNkjFqMmfN
jstl8kBwKQ8yyHtJ8vzOQr/qnRbK9fpZH/65uMOrH5oUYosEwfB+qg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPdy9GK1FPV3JaZDBsZmVX
T2RYSTRLd1dSZVZvb3Vxdnp2bThXSkZXSkQ4CjJ2b3M4bDJLNzdsaWdWOXlTWmsx
dWdDYVdEK0ROWkNEUWZMSUY2N0Q3d3MKLS0tIHRmOVl6d3hVUVJxdkkyTjZPQjFE
S2hWS3kzNW9jWFJKMjJjUU5qZmd4M2cKsabfN35q7aeA/QwC6QrzZkLHzNQAW8y6
Zbj+TwnXLcvJLkP2zRp3jJ4pwjj14bumnM5zwSq68HLvTSTZY1u9bQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:hae5SKE6XDTGYxxDb0ub7SctWLAHH2b+GygkrvtX70FUIdQdb7BAc7C/YMl11Z5hsIlFL3DYzJZmkz14E89rqFDs9g7xVYLi4rNyIAd4IfV9Ev5CNYHpsSZdcHq83cfUknD4lU7kjHidq9ITAh8xd1vRfPp+5CX41o5jLI83ohU=,iv:9tlwM7XCYnXC1oBUeuwK7N6SBjyJzHiDUiNLxfErU+c=,tag:1KfVyy+bN5oG63x8F1j66A==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -16,15 +16,11 @@ in
description = "Enable lazymount";
default = false;
};
};
config = mkIf cfg.enable
{
services.rpcbind.enable = true; # needed for NFS
environment.systemPackages = with pkgs; [ nfs-utils ];
systemd.mounts = lib.mkIf cfg.lazy [{
@ -32,7 +28,7 @@ in
mountConfig = {
Options = "noatime";
};
what = "daedalus.${config.mySystem.internalDomain}:/tank";
what = "${config.mySystem.nasAddress}:/tank";
where = "/mnt/nas";
}];
@ -45,9 +41,8 @@ in
}];
fileSystems."${config.mySystem.nasFolder}" = lib.mkIf (!cfg.lazy) {
device = "daedalus.${config.mySystem.internalDomain}:/tank";
device = "${config.mySystem.nasAddress}:/tank";
fsType = "nfs";
};
};
}

View file

@ -62,6 +62,5 @@ in
# required for using acme certs
users.users.nginx.extraGroups = [ "acme" ];
};
}

View file

@ -19,6 +19,4 @@ in
openFirewall = true;
};
}

View file

@ -1,77 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.node-red;
app = "node-red";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
appFolder = config.services.node-red.userDir;
inherit (config.services.node-red) user;
inherit (config.services.node-red) group;
url = "${app}.${config.networking.domain}";
in
{
options.mySystem.services.node-red =
{
enable = mkEnableOption "node-red";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
services.node-red = {
enable = true;
};
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString config.services.node-red.port}";
proxyWebsockets = true;
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
mySystem.services.homepage.home = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
description = "Workflow automation";
container = "${app}";
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "media";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app;
user = builtins.toString user;
excludePaths = [ "Backups" ];
paths = [ appFolder ];
inherit appFolder;
};
};
}

View file

@ -1,64 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.openvscode-server;
app = "openvscode-server";
url = "code-${config.networking.hostName}.${config.networking.domain}";
in
{
options.mySystem.services.openvscode-server =
{
enable = mkEnableOption "openvscode-server";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
services.openvscode-server = {
enable = true;
telemetryLevel = "off";
package = pkgs.unstable.openvscode-server; # TODO move to stable in 24.05?
# serverDataDir
user = "truxnell";
host = "0.0.0.0";
extraPackages = with pkgs;[ fish tmux ];
withoutConnectionToken = true;
};
services.nginx.virtualHosts."code-${config.networking.hostName}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString config.services.openvscode-server.port}";
proxyWebsockets = true;
};
};
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
"code-${config.networking.hostName}" = {
icon = "vscode.svg";
href = "https://${url}";
description = "Code editor";
container = "${app}";
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "services";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
};
}

View file

@ -9,13 +9,7 @@ let
app = "postgresql";
category = "services";
description = "Postgres RDMS";
# user = "%{user kah}"; #string
# group = "%{group kah}"; #string
# port = 1234; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
# host = "${app}" + (if cfg.dev then "-dev" else "");
# url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
@ -39,14 +33,6 @@ in
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
services.postgresql = {
enable = true;
identMap = ''
@ -72,8 +58,6 @@ in
location = "${config.mySystem.nasFolder}/backup/nixos/postgresql";
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
@ -81,8 +65,5 @@ in
# allowedUDPPorts = [ port ];
# };
};
}

View file

@ -1,110 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.powerdns;
persistentFolder = "${config.mySystem.persistentFolder}/nixos/pdns"; # TODO refactor using bind mounts
user = "pdns";
group = "pdns";
portDns = 5353; # avoiding conflict with adguardhome
portWebUI = 8081;
configDir = pkgs.writeTextDir "pdns.conf" "${pdnsConfig}";
# $APIKEY is replaced via envsubst in the pdns module
pdnsConfig = ''
expand-alias=yes
resolver=9.9.9.9:53
local-address=0.0.0.0:${builtins.toString portDns}
launch=gsqlite3
gsqlite3-database=${persistentFolder}/pdns.sqlite3
webserver=yes
webserver-address=0.0.0.0:${builtins.toString portWebUI}
webserver-allow-from=10.8.10.0/20
api=yes
api-key=$APIKEY
'';
in
{
options.mySystem.services.powerdns =
{
enable = mkEnableOption "powerdns";
openFirewall = mkEnableOption "Open firewall for ${app}" // {
default = true;
};
admin-ui = mkEnableOption "Powerdns-admin UI";
};
config = mkIf cfg.enable {
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"d ${persistentFolder} 0750 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
services.powerdns = {
enable = true;
extraConfig = pdnsConfig;
secretFile = config.sops.secrets."system/services/powerdns/apiKey".path;
};
sops.secrets."system/services/powerdns/apiKey" = {
sopsFile = ./secrets.sops.yaml;
restartUnits = [ "pdns.service" ];
};
# powerdns doesnt create the sqlite database for us
# so we gotta either do it manually once-off or do the below to ensure its created
# if the file is missing before service start
systemd.services.pdns.serviceConfig.ExecStartPre = lib.mkBefore [
(pkgs.writeScript "pdns-sqlite-init.sh"
''
#!${pkgs.bash}/bin/bash
pdns_folder="${persistentFolder}"
echo "INIT: Checking if pdns sqlite exists"
# Check if the pdns.sqlite3 file exists in the pdns folder
if [ ! -f "${persistentFolder}/pdns.sqlite3" ]; then
echo "INIT: No sqlite db found, initializing from pdns github schema..."
${pkgs.wget}/bin/wget -O "${persistentFolder}/schema.sqlite3.sql" https://raw.githubusercontent.com/PowerDNS/pdns/master/modules/gsqlite3backend/schema.sqlite3.sql
${pkgs.sqlite}/bin/sqlite3 "${persistentFolder}/pdns.sqlite3" < "${persistentFolder}/schema.sqlite3.sql"
${pkgs.busybox}/bin/chown pdns:pdns ${persistentFolder}/pdns.sqlite3
${pkgs.busybox}/bin/rm "${persistentFolder}/schema.sqlite3.sql"
fi
# Exit successfully
exit 0
''
)
];
networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ portWebUI portDns ];
allowedUDPPorts = [ portDns ];
};
mySystem.services.gatus.monitors = [
{
name = "${config.networking.hostName} split DNS";
group = "dns";
url = "${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString portDns}";
dns = {
query-name = "canary.trux.dev"; # special domain always present for testing
query-type = "A";
};
interval = "1m";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
];
};
}

View file

@ -1,51 +0,0 @@
system:
services:
powerdns:
apiKey: ENC[AES256_GCM,data:pQtycqEH,iv:mSFDKAvSTdQHXFWOcPpdU9qpT7gksyCmLLrZsco0f6A=,tag:xxNKhsYb7nNvY/tVjvb2Lw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4VWswY0E5dmhvNmRuWk5Q
QzRUTStEemwrZ2VSU3ZrbnFkc3ZWU201SlhJCkJKSzNORmtHbnBvVFBLNmxVNEps
WWR1TUdVTTJJYm9aY1FKL3NDbDB6NkkKLS0tIGh2SjIydU5OOXVHL1FyR0tjL1RJ
SVRqVE5RQTFYdi9GbFduUjJrN05RME0KTsOMRsER5UevR3H/g+1eMBxPWnYU+h9f
h2YSkPO/xDoYIJZl9ZMfH2kjvutKE4s6MzutDuZ941enlcOP5BDtww==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4TlZsME5wSkp5Q1VxTDd3
cU5taXU3M0xhbFdlK2lpZk53b3RaME4wQlNnCk5XLzZUbGl5YzF3OGUrVUNBMjlG
WkNyTUZJaUdjSEZwbzB0dnFwWUxnV0EKLS0tIG1kZEtCdXE0RTE3ZTh0ZU04b1pp
bzdZSHIwczVGd0RkcC9qRUJuRlZmaW8KnMO9asbe7iaSng0VlVD5Q+Z4kttrNYpR
yMyRiimyd8Vcb0o3ph/99ptWFZYTI0omVnsoMCkWcRoj8ZOgZZOYEA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJT0o4YzBXbHowcU5nd090
V1VEUFRlUFJRQ3pPRkprTytFR0lXeFpoNUI4CnNTVUQ0Q0tsMVpsQXpodWNYWFJp
OE1VeWt6ajJySmhiRXdjQlNiTmxoMUUKLS0tIGg1cy84Smh1R2xQZHRrcDdQZlhT
T1EzTjZrT3Z3NlNZeXNLYlJMaTVYK0kKUeVBmWLhyKLwcu5DNSc+B0Q9AQBq8Z1w
QZOa1EZQ5FPEZBtjg45P+uVKoERq8WlPeFawY0vRdBG3s1ZeErRR2Q==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRbTJhUEV2d1BBTUZKUnJJ
Nk0yWnZkcTZpNUdqVjc5TXlLRXNYd3J0djJBCjBnSWQ5aHRmbm5LbmxwemtrRUVO
c29XcVZjODFnK3l5OHR2bFFsbktUVG8KLS0tIFpaYVZKOURtcXU2ZG5ZV25QTkh1
Q0RGL2FQRmtNRlhTMHRtZ212RzY2K2sKWIHrTJl1jDinfREMDbgLaayvqH1SuwNL
pDyg9qM5gpY9ayNo5g6Xpgxq/wNNffcco9NDpekQOS40iYdq35cggQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:ZhJT03jkD2x9wH1HIwkN3RZbXG1OUna4ph1Xq7YNphpCdqz+IyPU0HpiZHxgB2KWnZTCcP8uh/2lrKDUImatX3Uhz7kLWUT+G/uKKzLT2RaNzjBuwL9CkIK/KnQBwBhiuW2TIjBDboFWnE3Y83ABMnvI06UChF5uE5cw4zjMxEk=,iv:Lx08otWjhrGMQP4bJxnlN+LvR8j1bvj0W7BMfcJqMYs=,tag:Eq6pR4H03Jx4BlHOhdh47w==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -46,8 +46,6 @@ in
description = "Enable local backups";
default = true;
};
};
config = mkIf cfg.enable {
@ -71,17 +69,6 @@ in
port = 9001;
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
@ -122,8 +109,5 @@ in
inherit appFolder;
};
};
}

View file

@ -9,12 +9,10 @@ let
app = "radicale";
category = "services";
description = "Contact/Calendar managment";
# image = "%{image}";
user = app; #string
group = app; #string
port = 5232; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
@ -90,17 +88,6 @@ in
};
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${ url }";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{

View file

@ -1,77 +1,50 @@
services:
radicale:
htpasswd: ENC[AES256_GCM,data:1UwfofyQcZicSUVhPumzw5g=,iv:y6Mm588YuxIM5u41hA7gtxAai9+AsvsLIyEBUHx79+8=,tag:jpuuBVlumhRFkQw777W9jA==,type:str]
htpasswd: ENC[AES256_GCM,data:4y6QUrivlOpUVNAGDuPb9w==,iv:AS13cN3EKDEfRCc6USejkYG4SEFS4sPoYrfok8jsfYg=,tag:60ZhYvH/+SQhZKR6M9Zlfw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYc3dCb0t3VkdlVXQvOVVp
SFRVMnRuRHdHSGxiOGxTRjJnaHhBWUQ0b2dRCnp6YmNZSTVVdnUvZXpIQ3ZmYjI4
cThjRk8zREU4dDhLNjVzeFhLUFVTUkUKLS0tIHJJcHZkSHFKdmVPNkFvZlV5UXpj
a0JLb0lWdlJGd3FqRFlXMFNWUk9yQUEKrsZP7IYj5Po07bvj513ZyZwlPnGecYnw
dC3LeW6ZhWtFNRl3y4xjZeAE4ghX0TyrGoHEMIjFUszid4sT2iHvnQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLc011SkxreTJSZERMemlS
clM0NnhPekF3bFZiUXUreDZEN3dkN3NmN0RNCmM3UEdlV3Azbk4yL2dpS3ZRQVpv
OWRQZ2E0eGU5cVIxRUU1c3RxMnpucEUKLS0tIHhjVXhtZEdVb3lvRnpoVGdJbkNq
WEM1bGRUOFVrOU5jbmhxSmpRK0F4WWsKoV2ABFGgcLb0qMmorOzNaAzPf6AbMfr0
PUdIkaXLJrF3Qi3bts96KhlPLUA7llArSMrUBtkXeCit6xS+87Imuw==
-----END AGE ENCRYPTED FILE-----
- recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuRHlaMlU5Y05HUHBxVFc2
WG96Rk41VUdYNS9KSmpvK0tiSnk3TUxZMkdNCnExNkVFYVcrOFRsM3g0YTJROFRq
VDU2bytVcWlvNUhpNWNCc25ldU5HMEEKLS0tIGswWkZYYnJwZmJXelVQc1R3N1Ju
elcvU0ZKMk9ocUlIQk1tVTNPeisxR3MKaeHf2BILzQHFlnFHWUEEILiFR7h/HOoT
6Xl018GPmmm+6cjJLNjdvvjcPlxwbakw6fRVdirsP5H3LRdBRDYvMA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBka1htN2tsN2ZZMkpDdHph
dk5EY1JkM0hONlRiaXFhdGVIT0xuVDA0b2tBCnlTVExGOHg5RFdiRzU0RWd3dEg3
aXB2UkhQRUF6QnBRN0FnNjRqMWIwRkUKLS0tIHJxOWNmR09PRVFQK1E3Um1laHJj
VmdPdHl0OGtGODBIZHVzelByaVVoRTAKWb7/Th4zdNFo+K+rwi+nHpbftxnnMOlt
BV0hsMpFBaQZXw01n9uw71MZiJZAbZOMA9P+toMKL9UwWSx+isa3gA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQckIwK0FBcnhRSXYvTlk2
TGZWR29KUmg1ampBWXBRUThVZFIyd2R6bTBJClRJdGVHazlGVDJoSVc3SDlkbVg1
U3hHTzFlQWRnekswUmwranUydm90QUkKLS0tIDNNaTdSbGZwOG1hSXlya1FEN2oz
Q0xUNDNpUFZHYkhjNncvUjdocmdYVUEKBMLMqLHvoxYciaSQM9cT0WBkIbrXE+x3
ZYtDfEQAu9FZvUqVYoGomR/0P1R/NNfhqHb1VAMuLKjB8d3obE0Gvg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNVTdVN1VnN1JpWkJFWC95
Qmc3dUNQdUtWSjRwWlVSVlJ2aGZ1MXIrMEFJCjNtck5vcGVhNnFQNXk2MjlHSC9P
aDU3WHQwbWdtbTBMcWdCUFE4Ulg5RlkKLS0tIGFDYnpGNE1SY2cvaUk4cWtBVmN6
VGRIaEpkUk1qN1RsakV2YkdCbGJhUGcK8l4O+ysy9MeOq5uqnzt9GdkkH53BPtFf
rmONh4pxPogBB0IsvZBz2NUsKkixnucEK0+SrF2X5x0wveMl/2Nm3Q==
-----END AGE ENCRYPTED FILE-----
- recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvMWtIcFJUQTM5UURaNUQx
VzJjcDU1QTZZUE5JYTAzOEpPYXhBdkpnVm04ClVHaWRTSTJxUm54NUV6M2o2c3U5
OXdmOE9ZT1h6dlN4Z2pVbHFZdENWQ2cKLS0tIHNrZ1hTQUxVSWxWcmYvcnBBbUkx
V1pQQUpsNEt0RXBVQUNFY2p5ejhOc1kK5nhUW8lEFa2m38mTGVnQGuRj2DMr+JJ0
9oEjLbMkZHfeYKSGDlkOPeG5f7Lp3qCJnJ7FHv6/TlL2tN4yVcUYxA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3d2FMMStGS2dSYVcxMHNM
QXdPenBQMXJlWFJWcHp0U0h0SkNpWWlNdXgwClBTMk1TQXg4M3ZueVZha1dNN1gv
cTNuS3hBblNPQjBCa3o3N2xyNG9EZWMKLS0tIEo5SVc1b04xZndSNXQ4T3BOTmtr
M1NVZkphS2E1R2c3dWovcHlaTloxTkUKsDiyHq40XddMdcZ/2UmOUnPSu44SWTRZ
ZcDiYbfU4R7Ysgqaxl2iqBun/GOPWf4yeAbcynwXsLMUGG+XnsRWVw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ekt5xz7u2xgdzgsrffhd9x22n80cn4thxd8zxjy2ey5vq3ca7gnqz25g5r
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnWXdDUW5RMHhnR3NzamI4
ZzhWVHBsWnRPSkJieGpuOEg1VDNzMHpVQXhnCmdGbVJRa3BQU0l0Mmk1aWI3eG0v
MlRZdEdkTmxuUnp0QVVSaFdpQVp1Z00KLS0tIHJzZ3BkdEcxUzNDRjZWaUhYOEJs
VTF3R2VscUtSSFJEZGN2Qk42TEJKMEEKeohZ/XNFDQSjwmWDSOfUg95S3SXLFqdl
hUNGRF32Sno7qE55fTPfK2uffb1Wocyjnt6Otp+Bmu0KUDGeBaBYLA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpNldwQlNGN25RYW9qanhh
bkg3c0VvY0ZFUHBjOE85VHJvODI3Y21GRmhRClFabkEwNWJMMy8rR3lmOUJaTElv
a1A4ajJkU3FnTitmZzhUQWNKckE2MUEKLS0tIE5iVUxzM2ZpOGdEc3VJSE54cjF0
L1h0TERMSm82N0ZYalB1QmZ0QUMxd2cKminvLq5ok5M44znw1etDknkNho7eohur
jgVEWEpn1vL570BVeNwZUcVRW2tUuMGgzznabkWTl19qMaxck//XiA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBraWx2dXpUaEhUS09GWXVx
T0daMWlDU2U1NDlCcUVlYkhBUWs2cXBYdHhrCnlTYThNQlJsZGZDRWJ2SUJWRVVW
QzBja2I1MWJ2YnN5d0NWMXRSbE43L1EKLS0tIHZETEpOQnZNT1JkYlEzNCtDS1FP
UWVaNG0vVXB0YjNXb0ZHeEFaZDVrSmsK3EKc2FhyfB4kG08hfBXRD/pJOyWwmjj8
qUns8YxX5KI2dI+P7UNH8uxzpbxhbfKIx1oCGRSsFfLkDfZPtRLKtg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-04-30T23:25:37Z"
mac: ENC[AES256_GCM,data:dadR/CZPmDYJCIFgbWdbu6hjNGrwc1IRk1IucAhVTOkuVQBCMhd4+Qv0CWG5Lc1O4juSblJDQbp9PGO/YCGfJ6jfLplBxlei7LTX45RbaChrPc/bVULSAXDZRjdQKVN/gb2HVgwh2PXXdR0IvYyDao55Repw+Va5qfSSa1FiHfg=,iv:nM1TwKOOB8Qr8f1l/ct32qrAV7dLhclu4SsRk/KcSSM=,tag:6fzeJyS/dPe7Bxm4WYBBwQ==,type:str]
lastmodified: "2024-05-18T16:39:41Z"
mac: ENC[AES256_GCM,data:9HLkT8t+LOSeVCWbjMhXMi7XduJ0nw4nZz9/dYCeyMW0w0/NscYn2avSUSks/5j14xAt4/NFmuM+KxW6z2dEdXE7DsCo1nWh+WyaTpL1QUId5xSWc6abQaexaKeRu/3QJ1wLNFgotaCuut96iFFTmvDL+t266ozxst8N3iR7zhk=,iv:NQwgSFv6Ogybrs6BMYl9eLeu0kNIJpmHR0MJCYHbCxA=,tag:X3BkmlHDt3E3GFT1iDYJHg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -35,8 +35,6 @@ in
};
};
config = {
# Warn if backups are disable and machine isnt a dev box
@ -65,8 +63,6 @@ in
};
};
# useful commands:
# view snapshots - zfs list -t snapshot
@ -106,8 +102,6 @@ in
mount -t zfs rpool/safe/persist@restic_nightly_snap ${cfg.mountPath}
'';
};
};
};
}

View file

@ -1,8 +1,8 @@
services:
restic:
password: ENC[AES256_GCM,data:0dA=,iv:CmmDdEsoyfZEsqfzFODsiskkQSBpOrrAmvPr109rMws=,tag:b34pv7e6pQpvn449TMXl4w==,type:str]
repository: ENC[AES256_GCM,data:OCctcQ==,iv:4KzR+WZx/2s8rFnLrjfUwOjIkH3E9IwRmCuxRHbEl3s=,tag:EzkhysnA+WUEjZP/BALGyw==,type:str]
env: ENC[AES256_GCM,data:zNCWLkFkT4VimYZoMPyRXg==,iv:k0m1ZK7gI3NPNWvkSLz4SlobD1ESyj+RP4W4DWweU5I=,tag:RC8ntYEJ9LC2J0qHUy2TJQ==,type:str]
password: ENC[AES256_GCM,data:23E=,iv:qK5OxK70KSC6nxsiovOWLDG1+6Mdlf+DNibc/mm3uGA=,tag:GV3V+T/Y8dO/L7pv+OkHzg==,type:str]
repository: ENC[AES256_GCM,data:Sbao4Q==,iv:M9asdh36DY4Ys3RHugTeduECunSkrcL9yjE0j+CaCTk=,tag:Nmy8LNJbwr7cOTQd1p/kqQ==,type:str]
env: ENC[AES256_GCM,data:wNFPsVW6DwZF6Qyyztt0Jw==,iv:PrP6gq+IMTUSKWIKt8zV8o1wbR51vZuZ95Yjwt07ypU=,tag:bBO0tYVR4qrSTZxMoQKgZA==,type:str]
sops:
kms: []
gcp_kms: []
@ -12,41 +12,41 @@ sops:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhbnFLZ3lqbHoxUmlXUEhT
dUJZRmVwVUdmbGxIc2NEN3I2UWpsYXVNdndvClNRTHV1UTVLYkhXdjBaRU1RNE5U
RExaUzVZNEhqemk5a09YazZHLzEwVEUKLS0tIDdCeGU5SnphK1BmaGRnWmxEalRI
Ti9lSmRHME9XMkdJeFBDVjRnVVNxQjQKU2DwTHVVnKqp9++LqSHBX0vXr6vQ6JIL
UuMgiXBrMai4F99tmJLxlUGrIA3gnMJ8+t/iPEyQ6LJMjQhbybXj8Q==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaMzZ0Y0FRaUdzY0tMeEx5
VUJxZkFRUlY3clI1ejVCT0xPNnN3NTh1OHhZCnh2YkxkemZ0ekwxT1NQKzIvTGlH
ejZISVJqVmM2UE1iM0M1eGpDSTN6VGcKLS0tIHJxSEhobUxoYWNXeE1LbWV6N0t1
dGluUjZCbjFMMktnMFhHSVRscUtUNFEKFAEjmLUA0/9iZLQ4EhpPgyYYYkzQCpUL
bo83xqeLmxY7jU8HGF2YNyBe+I9LHpZvxDTiXzBDiK0Bry9b57hWgg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEWGZqQk9CMkozaEs5RGpJ
azlxbDNHVFNRWVFGcjRxKzl2Q3l3ZnRQNTJjCklTeHd5bm9vWkFSYWFYV3dkVEdm
MVZJaElkVDI2b1d4aGpXaTd0dFpoQUUKLS0tIHNpV1Z1NnBwTWtrK3pIZXZCOHRW
dkFCbnlUVitXTGNMSkNySGZLZkM5NkkKiCriIwpURxB0BKF6YGKUlHlV3XTnGzFy
jbYvT7bj2PS7pZUaZvqmoFq3cmQD1W6dGWtEGu3F8l9YpHX5nKk0+w==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLS1diU0xaU0M0amJEajM3
YkpDeUh2VlNGa3liTFZMOGZYUDRoRUNGeldzCk5kSTcrOXNsclJTUnRoMEZqT0s5
WTVKcFh4WVlSY0JlYUp0QmF4dWhCWlEKLS0tIGhoeERZWmZCcHR5bEtRZW1JczFy
bEl2Yy9mb1NnbUx6WFFHUGhjUXNqV2cK4M0cAXzjNzG09g2FHCZUw8NQkw6Qw3o9
G3uFAkWw1Dny8PewS4tzOErAZlUQ0iKJDgUVqOrrBrfvctTFtBseAw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwQmt6bUV6OHMrVytvaWJz
Mm1IUUxQaHBFQUVMbUg4KzJLQTJLM0lGcWdzClVSME1VOEVJWkgweWsrNzlMSnRO
WDArVFBjT2dZWmkyNDZNb0NxemZRVW8KLS0tIEZZNjRoV3J6MW11djFxOGc0eEQ3
SXdacTVFcEJwdXRudlF4enFrbE00dU0KeInLc+T1BSSTBgsMnSJxtR2UH7BaCCrp
2CxHBwqdV490qI++GAuGOD633YrSWjJvKaNBrUt2IkhqCRU1rbYzGA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3WE9jVFRMRC9iNFVaTnNw
OEovY3hwYW5kWnlrSTRIbFU5enFJVXlFVTJjCkdueno5bXZFS0VPU2RWdk5PUTRj
Tk53UGJVZXZ3MExER2txVlRsVDIvY1kKLS0tIFI3VlNyYzB1S1RLS2JEbW54MTdW
aHpBN3ZqWENXc1cvZE5Xa2FiaHNlU0UKQ5/xk21o60JLZ6xNcB0cFHkoTXMN99LD
okhdVhlpml06ODoMIsFq/PR3adjeWJRjB7C4/Bz/wzlEUmze3TQMew==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwUUhiVkRJWEIwZWtDcHlF
L0l6cXhhL1YrSXBoVnhQNjU1VzJVYVIvaUJFCllGQVdGRGNKeFlGbHZ0YkdHamJV
bnlhN01GWGxvVjBBaXNBakF2M1VzZFUKLS0tIHJ0cm1qWWZBcXM5elNQdjVjampq
ZE5KeldzeUgxdEE5RlhaWk05eDk3ZGMKclNvmniziFtucvDeUuskIDNrVvaqR8xi
51IMQjrKDpXBDug/J2I6wCcSPfYGMBEJXuofBccHZcFflYgukfSFoQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3L0h2T3crY2JpaGMreS8z
YkJLOTMvbTRKUFNlWXgzZkpPUVJ5eDFON3pFCnBEeDg1YnpxNXZvdWtPbndRT1VZ
ZUhPRFE3TGFYaGluSDRjbkFHdi81NVEKLS0tIFJYZ3NaSVd6a25qMmxZV1VUNk50
Wmo2cHY4cUZFMkFlUmNKcmg2RjcrUncKmbMWBL8r6R777c3SvFmmRpRY2oRQsf+A
Yqlv0wmrD6A1B61SDRDwkmFggnk0PquznZD/y0JctqRqmcstAscyNQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:13Z"
mac: ENC[AES256_GCM,data:L1RXxt8t9fz1R1N5tBGOpSr4wn99EazFA24NUjtirNhNnp0wbea9UInb/U/j9PlgptM/G9M7Uh+WO35pw+htkTnpCkENyyAUb58pBKeG+185AFr3yl9u7+vTHkib3KIphQ4L40rwe1ws8/oGTrBUQZ87RuT2RIHwfjS0+GSW4hc=,iv:oX9ZQHUoc+2+EhE09Z8KMnz9cogFjZR1FTBxoks/O6g=,tag:zMVDEjIaCMcJyEX1JHym7w==,type:str]
lastmodified: "2024-05-18T16:39:41Z"
mac: ENC[AES256_GCM,data:sMTQ25VnUOrMSN9Ro7GoovFWh9Y/4RmHXm/mRHNuOGpl2utXGGQhAGM0F2lpdQwJfd/cRneiDfEJ1GSV+yaSPfTm2KFVVM+Kzl7AyHQO6W1dEvaMhJgGvxixc0SkF9zuU0WXnNOxW67fKUuuZZ69TwMdcVmwF1u7pV9tsONtgf8=,iv:Heynu00CnyU17zNkv1riz2hpulbXOeoi7ukj7c3Qk1g=,tag:Jqkaqq3XSXvENl/8a1z2QA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,136 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.${category}.${app};
app = "rss-bridge";
category = "services";
description = "rss feed for sites without";
# image = "%{image}";
inherit (config.services.rss-bridge) user;#string
inherit (config.services.rss-bridge) group;#string
port = 1234; #int
appFolder = "/var/lib/${app}";
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
host = "${app}" + (if cfg.dev then "-dev" else "");
url = "${host}.${config.networking.domain}";
in
{
options.mySystem.${category}.${app} =
{
enable = mkEnableOption "${app}";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
monitor = mkOption
{
type = lib.types.bool;
description = "Enable gatus monitoring";
default = true;
};
prometheus = mkOption
{
type = lib.types.bool;
description = "Enable prometheus scraping";
default = true;
};
addToDNS = mkOption
{
type = lib.types.bool;
description = "Add to DNS list";
default = true;
};
dev = mkOption
{
type = lib.types.bool;
description = "Development instance";
default = false;
};
backup = mkOption
{
type = lib.types.bool;
description = "Enable backups";
default = true;
};
};
config = mkIf cfg.enable {
## Secrets
# sops.secrets."${category}/${app}/env" = {
# sopsFile = ./secrets.sops.yaml;
# owner = user;
# group = group;
# restartUnits = [ "${app}.service" ];
# };
users.users.jahanson.extraGroups = [ group ];
## service
services.rss-bridge = {
enable = true;
whitelist = [ "*" ];
virtualHost = "${url}";
};
# homepage integration
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${url}";
inherit description;
};
}
];
### gatus integration
mySystem.services.gatus.monitors = mkIf cfg.monitor [
{
name = app;
group = "${category}";
url = "https://${url}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}
];
### Ingress
services.nginx.virtualHosts.${url} = {
forceSSL = true;
useACMEHost = config.networking.domain;
};
### firewall config
# networking.firewall = mkIf cfg.openFirewall {
# allowedTCPPorts = [ port ];
# allowedUDPPorts = [ port ];
# };
### backups
warnings = [
(mkIf (!cfg.backup && config.mySystem.purpose != "Development")
"WARNING: Backups for ${app} are disabled!")
];
services.restic.backups = mkIf cfg.backup (config.lib.mySystem.mkRestic
{
inherit app user;
paths = [ appFolder ];
inherit appFolder;
});
# services.postgresqlBackup = {
# databases = [ app ];
# };
};
}

View file

@ -1,39 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.syncthing;
in
{
options.mySystem.services.syncthing.enable = mkEnableOption "Syncthing";
options.mySystem.services.syncthing.openFirewall = mkEnableOption "Syncthing" // { default = true; };
config = mkIf cfg.enable {
services.syncthing = {
enable = true;
group = "users";
guiAddress = "0.0.0.0:8384";
settings.options.urAccepted = -1; # decline telemetry
openDefaultPorts = cfg.openFirewall;
};
mySystem.services.traefik.routers = [{
http.routers.syncthing = {
rule = "Host(`syncthing.${config.mySystem.domain}`)";
entrypoints = "websecure";
middlewares = "local-ip-only@file";
service = "syncthing";
};
http.routers.syncthing.loadbalancer.server = {
port = "8384";
};
}];
};
}

View file

@ -1,230 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
# ref: https://github.com/rishid/nix-config/blob/be0d5cbbe4df79ed2b2ba4714456f21777c72b38/modules/traefik/default.nix#L170
with lib;
let
cfg = config.mySystem.services.traefik;
# core dynamic options to define middleware
# sso etc
dynamicOptions = [{
http.middlewares = {
# Whitelist local network and VPN addresses
local-ip-only.ipWhiteList.sourceRange = [
"127.0.0.1/32" # localhost
"192.168.0.0/16" # RFC1918
"10.0.0.0/8" # RFC1918
"172.16.0.0/12" # RFC1918 (docker network)
];
# authelia = {
# # Forward requests w/ middlewares=authelia@file to authelia.
# forwardAuth = {
# # address = cfg.autheliaUrl;
# address = "http://127.0.0.1:9092/api/verify?rd=https://auth.dhupar.xyz:444/";
# trustForwardHeader = true;
# authResponseHeaders = [
# "Remote-User"
# "Remote-Name"
# "Remote-Email"
# "Remote-Groups"
# ];
# };
# };
# authelia-basic = {
# # Forward requests w/ middlewares=authelia-basic@file to authelia.
# forwardAuth = {
# address = "http://127.0.0.1:9092/api/verify?auth=basic";
# trustForwardHeader = true;
# authResponseHeaders = [
# "Remote-User"
# "Remote-Name"
# "Remote-Email"
# "Remote-Groups"
# ];
# };
# };
# https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview/#forwardauth-with-static-upstreams-configuration
# auth-headers = {
# browserXssFilter = true;
# contentTypeNosniff = true;
# forceSTSHeader = true;
# frameDeny = true;
# sslHost = domain;
# sslRedirect = true;
# stsIncludeSubdomains = true;
# stsPreload = true;
# stsSeconds = 315360000;
# };
};
tls.options.default = {
minVersion = "VersionTLS13";
sniStrict = true;
};
# Set up wildcard domain certificates for both *.hostname.domain and *.local.domain
http.routers = {
traefik = {
entrypoints = "websecure";
rule = "Host(`traefik-${config.networking.hostName}.${config.mySystem.domain}`)";
tls.certresolver = "letsencrypt";
tls.domains = [{
main = "${config.mySystem.domain}";
sans = "*.${config.mySystem.domain}";
}];
middlewares = "local-ip-only@file";
service = "api@internal";
};
};
}];
# Combine the above 'core 'options with the (dynamicOptions)
# list of ingress routers for each serfie defined in various
# modules (cfg.routers)
# this folds the list and iterates each element to add them together
dynamicOptionsAttrset = lib.foldl' (acc: elem: lib.recursiveUpdate acc elem) { } (dynamicOptions ++ cfg.routers);
routersFile = builtins.toFile "routers.yaml" (builtins.toJSON dynamicOptionsAttrset);
in
{
options.mySystem.services.traefik = {
enable = mkEnableOption "Traefik reverse proxy";
routers = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
description = "Routers to add to traefik";
default = [ ];
};
};
config = mkIf cfg.enable
{
# ensure folder exist and has correct owner/group
systemd.tmpfiles.rules = [
"f ${config.services.traefik.dataDir}/acme.json 0600 traefik ${config.services.traefik.group} -" #The - disables automatic cleanup, so the file wont be removed after a period
];
# put the dynamic configs in a file
# i put this in a file instead of piping directly into
# the traefik module, so that if i update the file
# with a new router nix doesnt restart traefik, it just updates
# the etc file and traefik picks up the changes.
environment.etc."traefik/config.yaml".source = routersFile;
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets."system/services/traefik/apiTokenFile".sopsFile = ./secrets.sops.yaml;
# Restart when secret changes
sops.secrets."system/services/traefik/apiTokenFile".restartUnits = [ "traefik.service" ];
systemd.services.traefik = {
serviceConfig.EnvironmentFile = [
config.sops.secrets."system/services/traefik/apiTokenFile".path
];
};
# add user to group to view files/storage
users.users.jahanson.extraGroups = [ "traefik" ];
services.traefik = {
# TODO refactor into subfiles
enable = true;
group = "podman"; # podman backend, required to access socket
dataDir = "${config.mySystem.persistentFolder}/traefik";
# Required so traefik is permitted to watch docker events
# group = "docker";
staticConfigOptions = {
global = {
checkNewVersion = false;
sendAnonymousUsage = false;
};
api.dashboard = true;
log.level = "DEBUG";
# Allow backend services to have self-signed certs
serversTransport.insecureSkipVerify = true;
providers = {
docker = {
endpoint = "unix:///var/run/podman/podman.sock";
exposedByDefault = false;
defaultRule = "Host(`{{ normalize .Name }}.${config.mySystem.domain}`)";
# network = "proxy";
};
file = {
filename = "/etc/traefik/config.yaml";
watch = true;
};
};
# Listen on port 80 and redirect to port 443
entryPoints.web = {
address = ":80";
http.redirections.entrypoint.to = "websecure";
};
# Run everything SSL
entryPoints.websecure = {
address = ":443";
http = {
tls = {
certresolver = "letsencrypt";
domains.main = "${config.mySystem.domain}";
domains.sans = "*.${config.mySystem.domain}";
};
};
http3 = { };
};
certificatesResolvers.letsencrypt.acme = {
dnsChallenge.provider = "cloudflare";
dnsChallenge.resolvers = [ "1.1.1.1:53" ];
keyType = "EC256";
storage = "${config.services.traefik.dataDir}/acme.json";
};
# };
};
# Dynamic configuration
# refer the etc file defined above with the build
# dynamic options
dynamicConfigFile = "/etc/traefik/config.yaml";
};
mySystem.services.homepage.infrastructure = [
{
"Traefik ${config.networking.hostName}" = {
icon = "traefik.png";
href = "https://traefik-${config.networking.hostName}.${config.mySystem.domain}/dashboard/";
description = "Reverse Proxy";
widget = {
type = "traefik";
url = "https://traefik-${config.networking.hostName}.${config.mySystem.domain}";
};
};
}
];
mySystem.services.gatus.monitors = [{
name = "Traefik ${config.networking.hostName}";
group = "infrastructure";
url = "https://traefik-${config.networking.hostName}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
};
}

View file

@ -1,79 +0,0 @@
system:
services:
#ENC[AES256_GCM,data:nOjY3Vj7zNlnAtqKP7gQ85bvNFYy9LTUEvFEr7+Zcjl+SHVtav/xSvouZvHfS2R1s5FUO/IHhAO/b5lo+7gS5rXWprtwpmxTz274Mw==,iv:TXSdzhn10kgG16OSIhbJNWnuBHYPto7KEJmI4plMPJM=,tag:PiS2lcOE59pcX/P4kSfhCw==,type:comment]
traefik:
apiTokenFile: ENC[AES256_GCM,data:y0MToeBoYzrlbHq6+7Z05A6qNgREyPc48GURsQlFf9vKnK1rEi+isezqJD1VMMy6QtOeJQrzCi22VrUYlEMV63sPOsHYK+el9Om6oa8WA2HrqMrAswDNZWGSXdX1RW98WQ==,iv:h0xIH6wnZloLz3EdlMEGkbz1L5Z9gOfnFnjWPupvevQ=,tag:nP8E0trNt/yhxWO0PDDCtg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrTjFjWnBoQkhWYVIzb1Av
OENjREtkN20xZnFIb1gya3RnY3grN3o4d1RVCmpwd0pwWi9QVTdKVUdxa0M4NzJk
L2pCRWQ5bUNpTlJ1WjArQ0tVd01HdXMKLS0tIGhvVjZMcmlpVUhzV1FmMVFJdVQv
YzFLUFZXZEpmWHpha2Z0U0dqb0hTaWMKvKvBprEyebIYK0fc61x49G/ATlGsXUkQ
HvStwbMhMKy2dctwtTiDSTPQyu3qLjHYqpFK0ePiTXxmIBMsEU3zGw==
-----END AGE ENCRYPTED FILE-----
- recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzZ0tkOHBOZC9vaVdBU1ND
bkdGalM0WDBLSzRIOGl6L09oYkFaSm1MaFNVCmpYMzFqTFkvY2VTWlNWQW5Lak84
RmlRYktQQ1ZrS3QzWXJNTUxhajJDRWMKLS0tIGVUemd2REMrdncrN0htTVZYOERq
YjJmOXVjbzVic0wrZzBPdHNEWWZ1WDQKarMJdvW4G2ox95IZ+Nc4cuTfc5hvUYh7
uPxsSwHwicfKJf7lbdDnQc9YQ/xwre0aget6rUvpqKUA4uzXy7AN2w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhamNwNFdtdlQrM1IzRnZS
V0I5T2RyN2pOa0IxMUNzRUFqN1ZJeUFRTnhBCkRDaEU4SlNhb0tCMFJBV2Q4N2Jy
QWFVSzVEU0p6TXF1b2IvUnUwNEZOZ00KLS0tIFB4ZGo5dWJtOVNvWWdvZFFPWnBr
U0F2N3ZLdEVLaGRBV0Y1SDlsSGowM1EKjTbBambxpqg4ahEhKn0ky66XXMA/NESL
QcGxQCpveOp2OFHswg2TMAjYcFeWyQD/GgR13ipSrHCWugoyMfqGOQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSNm9mYUN6VTZScWlaOTBz
Uk0xQnl0TlIvRlpid090Wk5ubnNPMk9GalhVCjc1aUlPVmE1bUdET3VVZ0NXMEdX
MlF5N0RNTm1xNHhTL2ZDVGVyeEFHb28KLS0tIGVwMFZuUmYyUGk5T21LdWtRendW
Sm9BUzhPSnFJMWJ3dmlObGJadmo0VHMKFDsnDSMx5Gr9i5lushxBkEWkEwLr/5HO
HNmzpSpIIf2cnKtSM3rw+a1Wq6l8kFX5KBE71Fxn59clbVlU1TTolA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ekt5xz7u2xgdzgsrffhd9x22n80cn4thxd8zxjy2ey5vq3ca7gnqz25g5r
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSU1dvUWU1UXZINzQ0NHlD
TllxbXl2Y29sN0d4MHBLVHlaRi9NYUJDcUc4CnJ0Y1VhWkpwN1Z1dmhjNkNFYlRn
WTB2eXM3NnVyK2Z2QVhHWmNtNzM5RjQKLS0tIGlKRFZoblhXTjNXd1ZsQms2Y25N
M3RDOTVvK25scFF4T1kra2lGUXN1S3cK1rVQdADhWxjZjvKtNNs8tzkwzi/VkGs7
AyPX8Eb5aMSmiF3e36CLAiF29nRqhV78Y+HglenbmzuEVGhPqVTMTw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPa1lCOHY0MWhFR2QxSHUv
ZHZjMFVmR282ZGpwMzNpKzFIR25rbVN5MjNnClk4YWZzeTQ1ek1ES2tQcnVGcXhJ
d0JaMkM1Wm1DUXpQK084Z0JyeGQwREkKLS0tIEw2bWZhWk9hbEZDdDVmUmwzQXBa
UHdOaXMyVFNyMmwwSTI0UzRYMEtzNTgK2SmnaLbnNxaD8hL5cl87b+671ekxzrCx
owPvUyleS9PKpF3b38qEbK5Jo+1rkoWHduV4fuGniTScrsaSVWXm/g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2Sm8xU1NkWHBOL2lZTDha
SFYvNCtxb3ZoeXhPd0Q1cUNES0JjKzRsUGx3CkZYcUFSdElucmNBekU4WjJvVDli
cW9RMi9tdUZjK0RBb2hnN0dBSkJMK1UKLS0tIGhrMlcrS1JvenJQOWp1OVdwOXdM
SFFlVmo2MWhFemRDYkwrL3pjeUovbGsKvcvOI7UAsuaNnlcR4jYhGFH3SWi4W9on
N+Wox9Hqr3ZLYtswpdAc6Zjzi1XBiEAaXEHWBFRLk0bSE9ZR9BZe6Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-04-25T02:28:14Z"
mac: ENC[AES256_GCM,data:0VhDlbDrYeK3aOqaeIqmQtTE4ubv+nmwQCx1GXIGB7qxs5qxQbx9UVO/xZJh08L8NBPtMwgM2LarvwBSqINjo9ekUkgKX9ezUMIJrvSN9DTarZiw6mBYLaKDF+sCB8/2C4mWNvzt9tBP94it/1d7lCzi/gutlGKzAyXVGIawwWI=,iv:UWueUfPPmUhMfacnmVW6jei+8Dm6AUykIFzqpNIYty8=,tag:ZIvY8e63TZ+n+rEp2VDWwg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,116 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
cfg = config.mySystem.services.zigbee2mqtt;
# persistentFolder = "${config.mySystem.persistentFolder}/${appFolder}/";
app = "zigbee2mqtt";
user = app;
group = app;
appFolder = config.services.zigbee2mqtt.dataDir;
port = 8080;
in
{
options.mySystem.services.zigbee2mqtt = {
enable = mkEnableOption "zigbee2mqtt";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
};
config = mkIf cfg.enable {
sops.secrets."services/mosquitto/mq/plainPassword.yaml" = {
sopsFile = ../mosquitto/secrets.sops.yaml;
owner = config.users.users.zigbee2mqtt.name;
inherit (config.users.users.zigbee2mqtt) group;
restartUnits = [ "${app}.service" ];
};
services.zigbee2mqtt = {
enable = true;
settings = {
homeassistant = true;
permit_join = false;
include_device_information = true;
frontend =
{
inherit port;
url = "https://${app}.${config.networking.domain}";
};
client_id = "z2m";
serial = {
port = "tcp://10.8.30.110:6638";
};
mqtt = {
server = "mqtt://mqtt.trux.dev:1883";
client_id = "z2m";
reject_unauthorized = true;
keepalive = 60;
version = 4;
user = "mq";
base_topic = "zigbee2mqtt";
password = "!${config.sops.secrets."services/mosquitto/mq/plainPassword.yaml".path} password";
};
availability = {
active.timeout = 10;
passive.timeout = 1500;
};
advanced = {
log_level = "debug";
network_key = [ 42 88 79 94 97 102 54 190 99 52 160 64 224 107 103 40 ];
pan_id = 62782;
last_seen = "ISO_8601";
};
experimental.new_api = true;
};
};
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
directories = [{ directory = appFolder; inherit user; inherit group; mode = "750"; }];
};
users.users.jahanson.extraGroups = [ app ];
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
useACMEHost = config.networking.domain;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true;
};
};
mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [
{
${app} = {
icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}";
description = "Zigbee bridge to MQTT";
container = "${app}";
};
}
];
mySystem.services.gatus.monitors = [{
name = app;
group = "services";
url = "https://${app}.${config.mySystem.domain}";
interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}];
services.restic.backups = config.lib.mySystem.mkRestic
{
inherit app appFolder;
user = builtins.toString user;
paths = [ appFolder ];
};
};
}

View file

@ -21,10 +21,7 @@ with lib;
type = lib.types.str;
default = "/persist";
};
};
config = lib.mkIf cfg.enable {
# move ssh keys
@ -45,7 +42,6 @@ with lib;
"/var/log" # persist logs between reboots for debugging
"/var/lib/cache" # cache files (restic, nginx, contaienrs)
"/var/lib/nixos" # nixos state
];
files = [
"/etc/machine-id"

View file

@ -14,7 +14,6 @@ in
type = lib.types.bool;
description = "If we want to auto optimise store";
default = true;
};
gc = {
enable = mkEnableOption "automatic garbage collection" // {
@ -27,13 +26,10 @@ in
default = true;
};
};
};
config.nix = {
optimise.automatic = cfg.autoOptimiseStore;
# automatically garbage collect nix store
gc = mkIf cfg.gc.enable {
# garbage collection
@ -42,8 +38,5 @@ in
options = "--delete-older-than 7d";
inherit (cfg.gc) persistent;
};
};
}

View file

@ -15,14 +15,12 @@ in
type = lib.types.bool;
description = "If password can be accepted for ssh (commonly disable for security hardening)";
default = false;
};
permitRootLogin = mkOption
{
type = types.enum [ "yes" "without-password" "prohibit-password" "forced-commands-only" "no" ];
description = "If root can login via ssh (commonly disable for security hardening)";
default = "no";
};
};
@ -42,8 +40,6 @@ in
# Allow forwarding ports to everywhere
GatewayPorts = "clientspecified";
};
};
};
}

View file

@ -29,7 +29,6 @@ in
description = "Notify on failed unit %i";
serviceConfig = {
Type = "oneshot";
# User = config.users.users.jahanson.name;
EnvironmentFile = config.sops.secrets."services/pushover/env".path;
};
@ -49,9 +48,7 @@ in
--form-string "title=Unit failure: '$1' on $2" \
--form-string "message=<b>$1</b> has failed on <b>$2</b><br><u>Journal tail:</u><br><br><i>$(journalctl -u $1 -n 10 -o cat)</i>" \
https://api.pushover.net/1/messages.json 2&>1
'';
};
};
}

View file

@ -8,9 +8,7 @@ let
in
{
options.mySystem.security = {
sshAgentAuth.enable = lib.mkEnableOption "openssh";
wheelNeedsSudoPassword = lib.mkOption {
type = lib.types.bool;
description = "If wheel group users need password for sudo";
@ -22,16 +20,13 @@ in
default = true;
};
};
config =
{
security = {
sudo.wheelNeedsPassword = cfg.wheelNeedsSudoPassword;
# Don't bother with the lecture or the need to keep state about who's been lectured
sudo.extraConfig = "Defaults lecture=\"never\"";
pam.sshAgentAuth.enable = cfg.sshAgentAuth.enable;
# Increase open file limit for sudoers
pam.loginLimits = mkIf cfg.increaseWheelLoginLimits [
{
@ -49,5 +44,4 @@ in
];
};
};
}

View file

@ -16,11 +16,9 @@ in
default = [ ];
};
};
# System packages deployed globally.
# This is NixOS so lets keep this liiight?
# Ideally i'd keep most of it to home-manager user only stuff
# and keep server role as light as possible
config.environment.systemPackages = cfg.packages;
}

View file

@ -10,7 +10,7 @@ in
timeZone = lib.mkOption {
type = lib.types.str;
description = "Timezone of system";
default = "Australia/Melbourne";
default = "America/Chicago";
};
hwClockLocalTime = lib.mkOption {
type = lib.types.bool;

View file

@ -14,11 +14,8 @@ with lib;
type = lib.types.listOf lib.types.str;
default = [ ];
};
};
config = lib.mkIf cfg.enable {
# setup boot
boot = {
supportedFilesystems = [
@ -28,22 +25,17 @@ with lib;
forceImportRoot = false; # if stuck on boot, modify grub options , force importing isnt secure
extraPools = cfg.mountPoolsAtBoot;
};
};
services.zfs = {
autoScrub.enable = true;
# Defaults to weekly and is a bit too regular for my NAS
autoScrub.interval = "monthly";
autoScrub.interval = "weekly";
trim.enable = true;
};
# Pushover notifications
environment.systemPackages = with pkgs; [
busybox
];
services.zfs.zed.settings = {
ZED_PUSHOVER_TOKEN = "$(${pkgs.busybox}/bin/cat ${config.sops.secrets.pushover-api-key.path})";
ZED_PUSHOVER_USER = "$(${pkgs.busybox}/bin/cat ${config.sops.secrets.pushover-user-key.path})";

View file

@ -2,9 +2,7 @@
, ...
}:
{
nur = inputs.nur.overlay;
# The unstable nixpkgs set (declared in the flake inputs) will
# be accessible through 'pkgs.unstable'
unstable-packages = final: _prev: {

View file

@ -14,21 +14,17 @@ with lib;
(modulesPath + "/installer/scan/not-detected.nix") # Generated by nixos-config-generate
./global
];
config = {
boot.tmp.cleanOnBoot = true;
mySystem = {
# basics for all devices
time.timeZone = "America/Chicago";
security.increaseWheelLoginLimits = true;
system.packages = [ pkgs.bat ];
domain = "hsn.dev";
internalDomain = "home.lan";
shell.fish.enable = true;
# But wont enable plugins globally, leave them for workstations
system.resticBackup.remote.location = "s3:https://x.r2.cloudflarestorage.com/nixos-restic";
};

View file

@ -6,7 +6,6 @@
# Make `nix repl '<nixpkgs>'` use the same nixpkgs as the one used by this flake.
environment.etc."nix/inputs/nixpkgs".source = "${nixpkgs}";
nix = {
# make `nix run nixpkgs#nixpkgs` use the same nixpkgs as the one used by this flake.
registry.nixpkgs.flake = nixpkgs;
channel.enable = false; # remove nix-channel related tools & configs, we use flakes instead.
@ -18,7 +17,6 @@
###
settings = {
# Enable flakes
experimental-features = [
"nix-command"
@ -27,31 +25,25 @@
# Substitutions
substituters = [
"https://cache.garnix.io"
"https://hsndev.cachix.org"
"https://nix-community.cachix.org"
"https://numtide.cachix.org"
];
trusted-public-keys = [
"hsndev.cachix.org-1:vN1/XGBZtMLnTFYDmTLDrullgZHSUYY3Kqt+Yg/C+tE="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
];
# Fallback quickly if substituters are not available.
connect-timeout = 25;
# Avoid copying unnecessary stuff over SSH
builders-use-substitutes = true;
trusted-users = [ "root" "@wheel" ];
warn-dirty = false;
# The default at 10 is rarely enough.
log-lines = lib.mkDefault 25;
};
};
}

View file

@ -1,9 +1,9 @@
services:
pushover:
env: ENC[AES256_GCM,data:kQSOPR+RUZZXcXqbK8Y+GAfMXljlrKJyxPmIeWN9GD/P0/sKwL+IyhvosZ9D8LiPksCiAKnn0g0KlGszbiOiS1juCTM2vF1h1r5o2sl8Qv4gGVv0FHUHofhlR/+4ZMIU,iv:CCZNo1Prqmu2OnX16Uf8Rxz/QoLI5auOeRfmwE47UR8=,tag:xyPAou+o2e3qWzJqCmD3pw==,type:str]
pushover-user-key: ENC[AES256_GCM,data:ixr36X/fTH79cZxZnOAq5MvUsvrAX4B+Iw0RAWgB,iv:Kjy2vW2YZOTRcamJcD30jeXJyGA/n6hmKxSDA8+63Qs=,tag:aW+fE1o8WoDFdgRA5kiJLg==,type:str]
pushover-api-key: ENC[AES256_GCM,data:TcoTh0scNEnZmqpRjThPqR5XAV6x0UqlopxD0IEM,iv:lmn9JTUxTIQLaW64YOkTWqQ35o76IQe7eZitkWKBQ4M=,tag:T7JHba7NSwI7Rc7nV4xX5w==,type:str]
jahanson-password: ENC[AES256_GCM,data:duTg2nl4qxyXVpiwWyA=,iv:Up2VFioPFTpQ9K/5DElwRm5YXQwT3qYU3RUEJNsYDmY=,tag:+0fvfQZ8zxFwwvoWMHGxvg==,type:str]
env: ENC[AES256_GCM,data:Ug92K492ytxkRMHTw6fmYKgpkz47gBg9aLxqivo+t5GejJbIU1cOewo88/7ASmslceTAiY57NcBTM56eHw7U9+HEq1IjX6RukM/OxZ27R4aMkLCdf1c7DNJ5GOOvX2Zo,iv:uVXUIervTvgLnr60oeWeysB08TR/jy9AjNMWLW75teo=,tag:l2ZGGzMKcVTdnKx5q7XJiA==,type:str]
pushover-user-key: ENC[AES256_GCM,data:EWMIbhjq6+CH958H661xlxcVNLSKWHgxVyjTCU50,iv:Ph6z7Tri64WoPnCbTtrCA2ziprID1VXg8rynx6j6OOg=,tag:MZvq0AE1gp9Ga/73s6MWOw==,type:str]
pushover-api-key: ENC[AES256_GCM,data:1rnQ/dgls1iLtx3efKT37PyrZyArVbRe7BjmKYqZ,iv:pRvkTjRtpf5PhXG555OR+TVmgzwmJnF8+Pb2wfbTKWU=,tag:3DFYTgLxQFQIT4qTP9cQgQ==,type:str]
jahanson-password: ENC[AES256_GCM,data:HPLOlKHCpQIhat5qKKg=,iv:AawKpXj+2ZfEXg/eO2On4qtqHsoxksdRxH6nr+/oTGE=,tag:4wWfOGXybP6B88iGdFMF9A==,type:str]
sops:
kms: []
gcp_kms: []
@ -13,41 +13,41 @@ sops:
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUTHBld3gyZWRKRnM2V3pG
ZWFwdXNNRFY0ckRtSDdRMDRtV1FiM1lnekFJCk94UUVXL0JXcVhwcUxNZTNkT2R0
RUQrL2N4aFdJbTlGZUNLUzlxV0trRHMKLS0tIHJkSStjdUhNaFpYRzVPSjljYTV3
d3p1MWZaNmxKRWRoMjdLems5L1ZxNU0Kz+uH3c+RCmcNm15OTkGku/nkr6HJxXqz
zW2xW0Z7pij8FjJTx3+AD/NF2sufYAEQSUDjZxg2qzxcHPkuLaaQng==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGSTUzM1RzZEFVZTJBdFAz
UnlYSmllNUdWa3BEa1BWQnBtbXZ1YTBnR25RClVIdy9YTUFyZ2VOdHlyVnNxTS9W
Smw5dDc2S053ZElsdHZpdTRQc2dCWGsKLS0tIGZXUzNMTFlxaVFWNE1GREphanBu
Rkdyd2lXUE5ucUVYT1FOZVlJR0hORGcKC5k9U3D+rfp4yEOx88APxmobjvOnf9jn
POshirAInB/FjEOCb6gwmX8Y/0KJK1A69vwrx3+C4S+8xWcTQwnHqA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKQXplYjZlL1VORHlOekVR
bG9UeEVUMnVXMnVRTHp5MnVDd04vQlNMWUNjCndlNXJ1eDhpMk5BcW1OUytLRUhv
THNyQVRUWkEvaUI2UUdjOFRUYUJvbHMKLS0tIGo3VVI5L2RPTG1SbXZqdlhEREpj
VndGbzE1SEFWcXNvbkRFemNMTCtpeXMKQm1KY5e0kAO4l8bDdCj5IEC/S7ntjCyj
dRqVlnmA8ClnyBo7HfURRbOxLK8iScKLDHVU0xo1CBGiEk5RLY8+Eg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMeCtkNnllZ3RHSjdVWHpq
N0pXM3B3RVJ2QnNwVXpvN2Q3R09mSFU1QWtnCnRvYnR6eVZCaEJkMjMxeEFzRHZ2
enVodXlHUVFGcEZpTnFHT1VkTGwzbFkKLS0tIFhCTzQ3Ny9TOVBTamZ5SHIzKzFZ
L2NsSjFGWHR4ZDBQR0FFZUdCUXpPRmcKdC6gSCxkHvThXEhp94b3Gx/5Tz4E2B6C
TcwMZVgCC2VkSMASj1Jg08AX+xmJ92gc2xl/v9hQ3MWJbR38KBkaBw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5YlBZTDQrN0JXblZnN3Yy
alNITnBCc21jMmMvczZwQVFoWEV1VkhSdVhFCjg3RDl1WFFaTXRIUzRoMW9jVU8y
WklEUjFxMHlMQVhIY3dNU3pxbkZlN3cKLS0tIFNDbWRJR1p5NWZoS0lUeHJRV0du
UldSMFh3S2U4ZkNrWGgvL1h4czRqUkUKxh04CjPIN2w/D/bw0V07BXVa4U7UNZrd
tp9WUhUhySZkSwS+TDAtEYWLVOayCojq5OfdrvNfgfmOsnek+t+HNQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvMk1XRjdHQUtYbnNrb1oy
SnlwVjBEUTd3dFdlaWh6UGlFTzR1RmpKYjE4CmhSKzFBOFFJSmtnM3Zwc3pKUy9j
SmJiNFhoVmd0ZzE0V2xDK0dzaGhZRGMKLS0tIHlqbWozZHV1R3JSclQ0ZWNRejlD
b1Q4RjJSWm1uSjRVNWd1WjBld1hUbk0KOB+7u0eLMslPCBE745dk7P8kVgELGp6m
glDmVIqsKmvutZ54AhCtI/pOuL5vlmnstRn8MCXcZgXbm3a80BSNFg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyZmg2L2ZCK2JXMHArUmw1
Z3BWQ2J0QkFzbmoyeVZIN1RZVng0c0NGRG5jCjlXM2ZmL21EaTJ2Wk9uRmlqUlow
dU55bFMyenluYUxVcFBEWUQ5UXovSkUKLS0tIGp3Y2lMMWdoNDBDeU9TUDRxc01v
TmxUK3B1QUNKcXNzVDg2M0hLOWpkWFkKuBAU1zDdTLjyeVxzcnVf34wo/mLSjKoh
YUysbhHwu7EVwgdX+OoRHyQFjWenPZ/IkLsjDuYrQ+3RDrpKDyWe3Q==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOcUFiQk5yMGJBUitabTB6
UHFVRXFVVWFoREV2dXZXcVJ0cG11TlhCUEVVCnAxQkJUUkU1VUhSaWNLQStpcUJu
ZzJBQjlUQXhuZk9PZXRJSktnQWFHZmcKLS0tIFI4TUNwREF5cXNXZEd1NUJ3MGFH
OFVrMXovMDVZTU5obE42NXkwektRa0UKmd1VNqD43WmhwICUohG2DLsZ9wYsGujp
IERwiWAiCppqOEULQeZti8ioPHJDs6tjpuAR+vZ1TD/uhdJP4xsfcA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-05-11T03:03:12Z"
mac: ENC[AES256_GCM,data:HEScCXJq4vBv8iJ9I/Ya9YtZWOKVKJlQsPrOMMt1zHVPxvDH/GZvDGJcJj63+1t4jkmr75z2ccH01ODcYgB82AISvckQYA/GBi/uQkQpvWuzzxpf11taIlikQjEogMDMDDlsjbHcJZjwQGQcPwr/HvPqGF6kzRHyxfwKb2ZUZ2w=,iv:1hAmBzMKqSk6hbsHOqhKCNoi4YIxhaItjr1nJrUk9ho=,tag:kyVDSJpr2bH4l3xzIwDo1Q==,type:str]
lastmodified: "2024-05-18T16:39:41Z"
mac: ENC[AES256_GCM,data:EXz+9dIdcI21WlJ9r/lewrfx9MjynA1eS82MMnO0BBiE2KV6XcMvrxStMIerXY/0nr2XGoZii8amo072naaHBTCwCsaDlx0Ry3oMyZYZNFwTM2mqIK93CymIkhe/qhMyNxDTmKc3QFEiRtimLnUx8YW27leS1b4mNFHcauXYNHA=,iv:EEmK39VBNXnJayk6z4MfHHsfj7OuwXUeLZQ06q2y2cE=,tag:9PLLS5BbwB1wmA+UV/oIwA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,6 +1,5 @@
{ config, ... }:
{
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
# Secret for machine-specific pushover
sops.secrets."services/pushover/env" = {
@ -12,5 +11,4 @@
sops.secrets.pushover-api-key = {
sopsFile = ./secrets.sops.yaml;
};
}

View file

@ -9,39 +9,6 @@ with lib;
'';
# Do not change unless you know what you are doing
stateVersion = "23.11"; # THERE BE DRAGONS
# (This one comes in the niiiiight) :::
# :: :::.
# \/, .:::::
# \), \`-._ :::888
# /\ \ `-. ::88888
# / \ | .( ::88
# /,. \ ; ( ` .:8888
# ), \ / ;`` :::888
# /_ \ __/_(_ :88
# `. ,`..-' `-._ \ / :8
# )__ `. `._ .\/.
# / `. ` `-._______m _,
# ,-=====-.-;' , ___________/ _,-_,'"`/__,-.
# C =-- ; `.`._ V V V -=-'"#==-._
# :, \ ,| UuUu _,......__ `-.__A_A_ -. ._ ,--._ ",`` `-
# || |`---' : uUuUu,' `'--...____/ `" `". `
# |` : \ UuUu:
# : / \ UuUu`-._
# \(_ `._ uUuUu `-.
# (_3 `._ uUu `._
# ``-._ `.
# `-._ `.
# `. \
# ) ;
# / /
# `. |\ ,' /
# ",_A_/\-| ` ,'
# `--..,_|_,-'\
# | \
# | \__
# |__
stateVersion = "23.11";
};
}

View file

@ -1,12 +1,8 @@
{ pkgs
, config
, ...
}:
{ pkgs, config, ... }:
let
ifTheyExist = groups: builtins.filter (group: builtins.hasAttr group config.users.groups) groups;
in
{
sops.secrets = {
jahanson-password = {
sopsFile = ./secrets.sops.yaml;
@ -38,7 +34,7 @@ in
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETR70eQJiXaJuB+qpI1z+jFOPbEZoQNRcq4VXkojWfU"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIATyScd8ZRhV7uZmrQNSAbRTs9N/Dbx+Y8tGEDny30sA"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJyA/yMPPo+scxBaDFUk7WeEyMAMhXUro5vi4feOKsJT jahanson@durincore"
]; # TODO do i move to ingest github creds?
];
# packages = [ pkgs.home-manager ];
};

Some files were not shown because too many files have changed in this diff Show more