Compare commits
11 Commits
60d0753c11
...
9523a36795
Author | SHA1 | Date | |
---|---|---|---|
9523a36795 | |||
3371942b33 | |||
2e5c13d8be | |||
f2f49f1819 | |||
02f9916be6 | |||
4fa2ec5f78 | |||
9b670ac6de | |||
c07ccfa42b | |||
c129c6adfb | |||
035cf0e555 | |||
a9f77a1b2b |
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,4 +4,5 @@ result*
|
||||
*.bak
|
||||
*.qcow2
|
||||
*.raw
|
||||
*.img
|
||||
*.img
|
||||
*.log
|
713
flake.lock
generated
713
flake.lock
generated
File diff suppressed because it is too large
Load Diff
30
flake.nix
30
flake.nix
@ -4,8 +4,6 @@
|
||||
inputs = {
|
||||
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/v1.4.0";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
# 6.1.55 kernel breaks podman. wait for fix
|
||||
nixpkgs-pinned.url = "github:nixos/nixpkgs/9eebdbb7182caf58dbbc11a4c221c23e867cca08";
|
||||
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||
flake-registry = {
|
||||
@ -17,11 +15,15 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
aagl.url = "github:ezKEa/aagl-gtk-on-nix";
|
||||
aagl = {
|
||||
url = "github:ezKEa/aagl-gtk-on-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
arkenfox-userjs = {
|
||||
url = "github:arkenfox/user.js";
|
||||
flake = false;
|
||||
};
|
||||
ataraxiasjel-nur.url = "github:AtaraxiaSjel/nur";
|
||||
attic.url = "github:zhaofengli/attic";
|
||||
base16.url = "github:AtaraxiaSjel/base16-nix";
|
||||
base16-tokyonight-scheme = {
|
||||
@ -33,7 +35,6 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
deploy-rs.url = "github:serokell/deploy-rs";
|
||||
devenv.url = "github:cachix/devenv";
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
@ -43,9 +44,7 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs"; # MESA/OpenGL HW workaround
|
||||
};
|
||||
hyprpaper = {
|
||||
# TODO: return to upstream after fix merge
|
||||
url = "github:AtaraxiaSjel/hyprpaper/fix-nix";
|
||||
# url = "github:hyprwm/hyprpaper";
|
||||
url = "github:hyprwm/hyprpaper";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
mms.url = "github:mkaito/nixos-modded-minecraft-servers";
|
||||
@ -66,20 +65,12 @@
|
||||
url = "github:nix-community/nixos-generators";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nur.url = "github:nix-community/NUR";
|
||||
# nur.url = "github:nix-community/NUR";
|
||||
prismlauncher.url = "github:AtaraxiaSjel/PrismLauncher/develop";
|
||||
rnix-lsp = {
|
||||
url = "github:nix-community/rnix-lsp";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
rycee = {
|
||||
url = "gitlab:rycee/nur-expressions";
|
||||
flake = false;
|
||||
};
|
||||
simple-nixos-mailserver = {
|
||||
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
@ -127,7 +118,10 @@
|
||||
"webhooks.patch"
|
||||
];
|
||||
sharedOverlays = [ flake-utils-plus.overlay inputs.sops-nix.overlays.default ];
|
||||
channelsConfig = { allowUnfree = true; android_sdk.accept_license = true; };
|
||||
channelsConfig = {
|
||||
allowUnfree = true; android_sdk.accept_license = true;
|
||||
permittedInsecurePackages = [ "electron-25.9.0" ];
|
||||
};
|
||||
channels.unstable.input = nixpkgs;
|
||||
channels.unstable.patches = patchesPath [ "zen-kernels.patch" "ydotoold.patch" ] ++ sharedPatches;
|
||||
channels.stable.input = inputs.nixpkgs-stable;
|
||||
@ -211,7 +205,7 @@
|
||||
name = "aliases";
|
||||
packages = with pkgs; [
|
||||
rebuild update-vscode upgrade upgrade-hyprland
|
||||
nixfmt nixpkgs-fmt statix vulnix deadnix git deploy-rs
|
||||
nixfmt-rfc-style nixpkgs-fmt statix vulnix deadnix git deploy-rs
|
||||
fup-repl ssh-to-pgp sops
|
||||
];
|
||||
};
|
||||
|
@ -1,4 +1,6 @@
|
||||
{ config, inputs, ... }: {
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
|
||||
|
||||
sops.secrets.rustic-nas-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||
sops.secrets.rclone-rustic-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||
services.rustic.backups = rec {
|
||||
|
@ -21,7 +21,7 @@ in {
|
||||
customProfiles.hoyolab
|
||||
customProfiles.inpx-web
|
||||
customProfiles.it-tools
|
||||
customProfiles.joplin-server
|
||||
# customProfiles.joplin-server
|
||||
customProfiles.media-stack
|
||||
customProfiles.minio
|
||||
customProfiles.nginx
|
||||
|
@ -1,4 +1,6 @@
|
||||
{ config, inputs, ... }: {
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
|
||||
|
||||
sops.secrets.rustic-vps-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||
sops.secrets.rclone-rustic-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||
services.rustic.backups = rec {
|
||||
@ -31,7 +33,7 @@
|
||||
ignore-devid = true;
|
||||
group-by = "label";
|
||||
sources = [{
|
||||
source = "/srv/marzban /srv/nextcloud/config /srv/nextcloud/data";
|
||||
source = "/srv/marzban";
|
||||
}];
|
||||
};
|
||||
forget = {
|
||||
|
@ -1,5 +1,6 @@
|
||||
{ config, pkgs, lib, inputs, ... }:
|
||||
{ config, pkgs, inputs, ... }:
|
||||
let
|
||||
inherit (pkgs.hostPlatform) system;
|
||||
cert-key = config.sops.secrets."cert.key".path;
|
||||
cert-pem = config.sops.secrets."cert.pem".path;
|
||||
nginx-conf = config.sops.secrets."nginx.conf".path;
|
||||
@ -25,16 +26,6 @@ in {
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers = {
|
||||
nextcloud = {
|
||||
autoStart = true;
|
||||
image = "docker.io/nextcloud:stable";
|
||||
ports = [ "9765:80" ];
|
||||
volumes = [
|
||||
"/srv/nextcloud/html:/var/www/html"
|
||||
"/srv/nextcloud/config:/var/www/html/config"
|
||||
"/srv/nextcloud/data:/var/www/html/data"
|
||||
];
|
||||
};
|
||||
marzban = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/gozargah/marzban:v0.4.1";
|
||||
@ -57,10 +48,20 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
services.ocis = {
|
||||
enable = true;
|
||||
package = inputs.ataraxiasjel-nur.packages.${system}.ocis-bin;
|
||||
configDir = "/srv/ocis/config";
|
||||
baseDataPath = "/srv/ocis/data";
|
||||
environment = {
|
||||
OCIS_INSECURE = "false";
|
||||
OCIS_URL = "https://cloud.ataraxiadev.com";
|
||||
PROXY_HTTP_ADDR = "127.0.0.1:9200";
|
||||
PROXY_TLS = "false";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /srv/marzban 0755 root root -"
|
||||
"d /srv/nextcloud/html 0755 33 33 -"
|
||||
"d /srv/nextcloud/config 0755 33 33 -"
|
||||
"d /srv/nextcloud/data 0755 33 33 -"
|
||||
];
|
||||
}
|
@ -1,320 +0,0 @@
|
||||
# Thanks for original module, anpin! https://gist.github.com/anpin/ecbdb6625400908856ef9482eca3380c
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.authentik;
|
||||
databaseActuallyCreateLocally = cfg.database.createLocally
|
||||
&& cfg.database.host == "/run/postgresql";
|
||||
|
||||
inherit (lib)
|
||||
mkIf mkEnableOption mkOption types mdDoc literalExpression optional attrsets;
|
||||
inherit (attrsets) optionalAttrs;
|
||||
inherit (types) str bool port submodule package nullOr path enum;
|
||||
|
||||
hostWithPort = h: p: "${h}:${toString p}";
|
||||
|
||||
authentikBaseService = {
|
||||
after = [ "network.target" ]
|
||||
++ optional databaseActuallyCreateLocally "postgresql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ cfg.package ];
|
||||
environment = let
|
||||
listenAddress = hostWithPort cfg.listen.address;
|
||||
in {
|
||||
AUTHENTIK_REDIS__HOST = cfg.redis.host;
|
||||
AUTHENTIK_REDIS__PORT = toString cfg.redis.port;
|
||||
|
||||
AUTHENTIK_POSTGRESQL__HOST = cfg.database.host;
|
||||
AUTHENTIK_POSTGRESQL__PORT = mkIf (cfg.database.port != null) "${toString cfg.database.port}";
|
||||
AUTHENTIK_POSTGRESQL__USER = cfg.database.user;
|
||||
AUTHENTIK_POSTGRESQL__NAME = cfg.database.name;
|
||||
|
||||
AUTHENTIK_LISTEN__HTTP = listenAddress cfg.listen.http;
|
||||
AUTHENTIK_LISTEN__HTTPS = listenAddress cfg.listen.https;
|
||||
|
||||
# initial password for admin user
|
||||
AUTHENTIK_BOOTSTRAP_PASSWORD = cfg.defaultPassword;
|
||||
|
||||
# disable outbound connections
|
||||
AUTHENTIK_DISABLE_UPDATE_CHECK = "true";
|
||||
AUTHENTIK_ERROR_REPORTING__ENABLED = "false";
|
||||
AUTHENTIK_DISABLE_STARTUP_ANALYTICS = "true";
|
||||
AUTHENTIK_AVATARS = "initials";
|
||||
|
||||
AUTHENTIK_LOG_LEVEL = cfg.logLevel;
|
||||
};
|
||||
serviceConfig = {
|
||||
User = "authentik";
|
||||
Group = "authentik";
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
WorkingDirectory = cfg.package;
|
||||
DynamicUser = true;
|
||||
RuntimeDirectory = "authentik";
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync";
|
||||
ConfigurationDirectory = "authentik";
|
||||
StateDirectoryMode = "0750";
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.services.authentik = {
|
||||
enable = mkEnableOption "Enables Authentik service";
|
||||
|
||||
package = mkOption {
|
||||
type = package;
|
||||
default = pkgs.authentik;
|
||||
defaultText = literalExpression "pkgs.authentik";
|
||||
description = mdDoc "Authentik package to use.";
|
||||
};
|
||||
|
||||
defaultPassword = mkOption {
|
||||
description = mdDoc "Default admin password. Only read on first startup.";
|
||||
type = str;
|
||||
default = "change-me";
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
description = mdDoc
|
||||
"Log level for the server and worker containers. Setting the log level to trace will include sensitive details in logs, so it shouldn't be used in most cases.";
|
||||
type = enum [ "trace" "debug" "info" "warning" "error" ];
|
||||
default = "info";
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
description = mdDoc "Listen ports";
|
||||
default = { };
|
||||
type = submodule {
|
||||
options = {
|
||||
http = mkOption {
|
||||
description = mdDoc "HTTP port.";
|
||||
type = port;
|
||||
default = 9000;
|
||||
};
|
||||
https = mkOption {
|
||||
description = mdDoc "HTTPS port.";
|
||||
type = port;
|
||||
default = 9443;
|
||||
};
|
||||
address = mkOption {
|
||||
description = mdDoc "Address to listen on.";
|
||||
type = str;
|
||||
default = "0.0.0.0";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
redis = {
|
||||
createLocally = mkOption {
|
||||
description = mdDoc "Configure local Redis server for Authentik.";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
description = mdDoc "Redis host.";
|
||||
type = str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
description = mdDoc "Redis port.";
|
||||
type = port;
|
||||
default = 31637;
|
||||
};
|
||||
};
|
||||
ssl = {
|
||||
cert = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = "SSL from NIXOS";
|
||||
};
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
example = "/var/lib/authentik/secrets/db-password";
|
||||
description = mdDoc ''
|
||||
Environment variables including :
|
||||
- Secret key used for cookie signing and unique user IDs, don't change this after the first install.
|
||||
'';
|
||||
};
|
||||
|
||||
database = {
|
||||
createLocally = mkOption {
|
||||
description =
|
||||
mdDoc "Configure local PostgreSQL database server for authentik.";
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = str;
|
||||
default = "/run/postgresql";
|
||||
example = "192.168.23.42";
|
||||
description = mdDoc "Database host address or unix socket.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = nullOr port;
|
||||
default = if cfg.database.createLocally then null else 5432;
|
||||
defaultText = literalExpression ''
|
||||
if config.database.createLocally then null else 5432
|
||||
'';
|
||||
description = mdDoc "Database host port.";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = "authentik";
|
||||
description = mdDoc "Database name.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = str;
|
||||
default = "authentik";
|
||||
description = mdDoc "Database user.";
|
||||
};
|
||||
};
|
||||
|
||||
outposts = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
ldap = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable =
|
||||
mkEnableOption (lib.mdDoc "the authentik ldap outpost");
|
||||
package = mkOption {
|
||||
type = path;
|
||||
default = pkgs.authentik-outposts.ldap;
|
||||
};
|
||||
host = mkOption {
|
||||
type = str;
|
||||
default = if cfg.outposts.ldap.insecure then
|
||||
"http://127.0.0.1:${toString cfg.listen.http}"
|
||||
else
|
||||
"https://127.0.0.1:${toString cfg.listen.https}";
|
||||
};
|
||||
insecure = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
environmentFile = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
example = "/var/lib/authentik-ldap/secrets/env";
|
||||
description = mdDoc ''
|
||||
Environment variables including :
|
||||
- API TOKEN
|
||||
'';
|
||||
};
|
||||
listen = mkOption {
|
||||
description = mdDoc "Listen ports";
|
||||
default = { };
|
||||
type = submodule {
|
||||
options = {
|
||||
ldap = mkOption {
|
||||
description = mdDoc "LDAP port.";
|
||||
type = port;
|
||||
default = 3389;
|
||||
};
|
||||
ldaps = mkOption {
|
||||
description = mdDoc "LDAPS port.";
|
||||
type = port;
|
||||
default = 6636;
|
||||
};
|
||||
address = mkOption {
|
||||
description = mdDoc "Address to listen on.";
|
||||
type = str;
|
||||
default = "0.0.0.0";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { ldap = { enable = false; }; };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.authentik = {
|
||||
isSystemUser = true;
|
||||
home = cfg.package;
|
||||
group = "authentik";
|
||||
};
|
||||
users.groups.authentik = { };
|
||||
|
||||
services.postgresql = mkIf databaseActuallyCreateLocally {
|
||||
enable = true;
|
||||
ensureUsers = [{
|
||||
name = cfg.database.name;
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
};
|
||||
|
||||
services.redis.servers.authentik =
|
||||
mkIf (cfg.redis.createLocally && cfg.redis.host == "127.0.0.1") {
|
||||
enable = true;
|
||||
port = cfg.redis.port;
|
||||
bind = "127.0.0.1";
|
||||
};
|
||||
|
||||
systemd.services.authentik-server = authentikBaseService // {
|
||||
serviceConfig = authentikBaseService.serviceConfig // {
|
||||
ExecStart = "${cfg.package}/bin/ak server";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.authentik-worker = authentikBaseService // {
|
||||
serviceConfig = authentikBaseService.serviceConfig // {
|
||||
ExecStart = "${cfg.package}/bin/ak worker";
|
||||
};
|
||||
};
|
||||
|
||||
# systemd.services.authentik-ssl-import = authentikBaseService // {
|
||||
# before = [ "authentik-server.service" ];
|
||||
# serviceConfig = authentikBaseService.serviceConfig // {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = true;
|
||||
# ExecStart = ''
|
||||
# ${cfg.package}/bin/ak import_certificate --name "${cfg.ssl.name}" --certificate "${cfg.ssl.cert}" --private-key "${cfg.ssl.key}"'';
|
||||
# };
|
||||
# };
|
||||
|
||||
systemd.services.authentik-ldap-outpost = let
|
||||
ldapCfg = cfg.outposts.ldap;
|
||||
in mkIf ldapCfg.enable (authentikBaseService // {
|
||||
description = "authentik ldap outpost";
|
||||
environment = let listenAddress = hostWithPort ldapCfg.listen.address;
|
||||
in {
|
||||
AUTHENTIK_HOST = ldapCfg.host;
|
||||
AUTHENTIK_LISTEN__LDAP = listenAddress ldapCfg.listen.ldap;
|
||||
AUTHENTIK_LISTEN__LDAPS = listenAddress ldapCfg.listen.ldaps;
|
||||
} // optionalAttrs ldapCfg.insecure { AUTHENTIK_INSECURE = "true"; };
|
||||
serviceConfig = authentikBaseService.serviceConfig // {
|
||||
ExecStart = "${cfg.outposts.ldap.package}/bin/ldap";
|
||||
EnvironmentFile = ldapCfg.environmentFile;
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
@ -58,13 +58,13 @@ with lib;
|
||||
HEADSCALE_CLI_ADDRESS = "wg.ataraxiadev.com:443";
|
||||
};
|
||||
script = ''
|
||||
auth_key=$(headscale preauthkeys create -e ${cfg.expire} -u ${cfg.user} -o json ${optionalString cfg.ephemeral "--ephemeral"} | jq -r .key)
|
||||
if [ "$auth_key" = "null" ]; then
|
||||
echo "Cannot retrieve auth key." >&2
|
||||
exit 1
|
||||
else
|
||||
echo $auth_key > "${cfg.outPath}"
|
||||
fi
|
||||
while true; do
|
||||
auth_key=$(headscale preauthkeys create -e ${cfg.expire} -u ${cfg.user} -o json ${optionalString cfg.ephemeral "--ephemeral"} | jq -r .key)
|
||||
[[ "$auth_key" = "null" ]] || break
|
||||
echo "Cannot retrieve auth key. Will try again after 5 seconds." >&2
|
||||
sleep 5
|
||||
done
|
||||
echo $auth_key > "${cfg.outPath}"
|
||||
'';
|
||||
serviceConfig = {
|
||||
EnvironmentFile = config.sops.secrets.headscale-api-env.path;
|
||||
|
@ -1,80 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.kes;
|
||||
format = pkgs.formats.yaml { };
|
||||
configFile = format.generate "config.yaml" cfg.settings;
|
||||
port = strings.toInt (lists.last (strings.splitString ":" cfg.settings.address));
|
||||
in
|
||||
{
|
||||
options.services.kes = {
|
||||
enable = mkEnableOption (mdDoc "Minio's Key Managament Server");
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
description = mdDoc "Which package to use for the kes instance.";
|
||||
default = pkgs.minio-kes;
|
||||
};
|
||||
environmentFile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
File in the format of an EnvironmentFile as described by systemd.exec(5).
|
||||
'';
|
||||
};
|
||||
settings = mkOption {
|
||||
type = format.type;
|
||||
default = { address = "0.0.0.0:7373"; };
|
||||
example = literalExpression ''
|
||||
{
|
||||
address = "0.0.0.0:7373";
|
||||
cache = {
|
||||
expiry = {
|
||||
any = "5m0s";
|
||||
unused = "20s";
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = mdDoc ''
|
||||
KES Configuration.
|
||||
Refer to <https://github.com/minio/kes/blob/master/server-config.yaml>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.kes = {
|
||||
description = "KES";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
path = [ cfg.package ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
ExecStart = "${cfg.package}/bin/kes server --config ${configFile}";
|
||||
User = "kes";
|
||||
Group = "kes";
|
||||
# WorkingDirectory = "/etc/kes";
|
||||
|
||||
AmbientCapabilities = mkIf (port < 1024) ["CAP_NET_BIND_SERVICE"];
|
||||
LimitNOFILE = 65536;
|
||||
ProtectProc = "invisible";
|
||||
SendSIGKILL = "no";
|
||||
TasksMax = "infinity";
|
||||
TimeoutStopSec = "infinity";
|
||||
} // optionalAttrs (cfg.environmentFile != null) {
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
users.groups.kes = { };
|
||||
users.users.kes = {
|
||||
description = "KES user";
|
||||
group = "kes";
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
}
|
159
modules/ocis.nix
159
modules/ocis.nix
@ -1,159 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.ocis;
|
||||
format = pkgs.formats.yaml { };
|
||||
|
||||
linkConfigs = confDir: lib.pipe cfg.settings [
|
||||
(lib.attrsets.mapAttrs (n: v: format.generate "${n}.yaml" v))
|
||||
(lib.mapAttrsToList (n: v: "ln -sf ${v} ${confDir}/${n}.yaml"))
|
||||
(lib.concatStringsSep "\n")
|
||||
];
|
||||
|
||||
mkExport = { arg, value }: "export ${arg}=${value}";
|
||||
adminpass = {
|
||||
arg = "ADMIN_PASSWORD";
|
||||
value = ''"$(<"${toString cfg.adminpassFile}")"'';
|
||||
};
|
||||
in
|
||||
{
|
||||
options.services.ocis = {
|
||||
enable = mkEnableOption (lib.mdDoc "ownCloud Infinite Scale Stack");
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
description = lib.mdDoc "Which package to use for the ocis instance.";
|
||||
default = pkgs.ocis-bin;
|
||||
};
|
||||
configDir = mkOption {
|
||||
default = "/var/lib/ocis/.config";
|
||||
type = types.path;
|
||||
description = lib.mdDoc "The config directory. Set OCIS_CONFIG_DIR env variable.";
|
||||
};
|
||||
baseDataPath = mkOption {
|
||||
default = "/var/lib/ocis";
|
||||
type = types.path;
|
||||
description = lib.mdDoc "The base data directory. Set OCIS_BASE_DATA_PATH env variable.";
|
||||
};
|
||||
environment = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
OCIS_URL = "https://localhost:9200";
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc "Environment variables to pass to ocis instance.";
|
||||
};
|
||||
environmentFile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
File in the format of an EnvironmentFile as described by systemd.exec(5).
|
||||
'';
|
||||
};
|
||||
adminpassFile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
The full path to a file that contains the admin's password. Must be
|
||||
readable by user `ocis`. The password is set only in the initial
|
||||
setup of Ocis by the systemd service `ocis-init.service`.
|
||||
'';
|
||||
};
|
||||
settings = mkOption {
|
||||
type = with types; attrsOf format.type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
auth-bearer = {
|
||||
tracing = {
|
||||
enabled = true;
|
||||
};
|
||||
};
|
||||
proxy = {
|
||||
user_oidc_claim = "preferred_username";
|
||||
user_cs3_claim = "username";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
OCIS configuration. Refer to
|
||||
<https://doc.owncloud.com/ocis/next/deployment/services/services.html>
|
||||
for details on supported values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '${cfg.configDir}' - ocis ocis - -"
|
||||
"d '${cfg.baseDataPath}' - ocis ocis - -"
|
||||
];
|
||||
systemd.services.ocis-init = rec {
|
||||
before = [ "ocis-server.service" ];
|
||||
requiredBy = [ "ocis-server.service" ];
|
||||
path = [ cfg.package ];
|
||||
environment = {
|
||||
OCIS_CONFIG_DIR = cfg.configDir;
|
||||
OCIS_BASE_DATA_PATH = cfg.baseDataPath;
|
||||
} // cfg.environment;
|
||||
script = ''
|
||||
${lib.optionalString (cfg.settings != { }) "${linkConfigs environment.OCIS_CONFIG_DIR}"}
|
||||
if [ ! -f "$OCIS_CONFIG_DIR/ocis.yaml" ]; then
|
||||
${
|
||||
lib.optionalString (cfg.adminpassFile != null) ''
|
||||
if [ ! -r "${cfg.adminpassFile}" ]; then
|
||||
echo "adminpassFile ${cfg.adminpassFile} is not readable by ocis:ocis! Aborting..."
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$(<${cfg.adminpassFile})" ]; then
|
||||
echo "adminpassFile ${cfg.adminpassFile} is empty!"
|
||||
exit 1
|
||||
fi
|
||||
${mkExport adminpass}
|
||||
''
|
||||
}
|
||||
ocis init
|
||||
fi
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
StateDirectory = "ocis";
|
||||
User = "ocis";
|
||||
Group = "ocis";
|
||||
} // optionalAttrs (cfg.environmentFile != null) {
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.ocis-server = {
|
||||
description = "ownCloud Infinite Scale Stack";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ cfg.package ];
|
||||
environment = {
|
||||
OCIS_CONFIG_DIR = cfg.configDir;
|
||||
OCIS_BASE_DATA_PATH = cfg.baseDataPath;
|
||||
OCIS_URL = "https://localhost:9200";
|
||||
PROXY_HTTP_ADDR = "127.0.0.1:9200";
|
||||
} // cfg.environment;
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
ExecStart = "${cfg.package}/bin/ocis server";
|
||||
User = "ocis";
|
||||
Group = "ocis";
|
||||
LimitNOFILE = 65536;
|
||||
} // optionalAttrs (cfg.environmentFile != null) {
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
users.groups.ocis = { };
|
||||
users.users.ocis = {
|
||||
description = "Ocis Daemon User";
|
||||
group = "ocis";
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
}
|
@ -19,6 +19,7 @@ with lib;
|
||||
}));
|
||||
default = { };
|
||||
};
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
|
||||
config = mkIf (config.backups.postgresql != { }) {
|
||||
sops.secrets.rclone-postgresql-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||
sops.secrets.rustic-postgresql-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||
|
@ -1,324 +0,0 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
|
||||
inherit (utils.systemdUtils.unitOptions) unitOption;
|
||||
settingsFormat = pkgs.formats.toml {};
|
||||
in
|
||||
{
|
||||
options.services.rustic.backups = mkOption {
|
||||
description = lib.mdDoc ''
|
||||
Periodic backups to create with Rustic.
|
||||
'';
|
||||
type = types.attrsOf (types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
settings = mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = {};
|
||||
description = lib.mdDoc ''
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
file containing the credentials to access the repository, in the
|
||||
format of an EnvironmentFile as described by systemd.exec(5)
|
||||
'';
|
||||
};
|
||||
|
||||
extraEnvironment = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
http_proxy = "http://server:12345";
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc "Environment variables to pass to rustic.";
|
||||
};
|
||||
|
||||
rcloneOptions = mkOption {
|
||||
type = with types; nullOr (attrsOf (oneOf [ str bool ]));
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Options to pass to rclone to control its behavior.
|
||||
See <https://rclone.org/docs/#options> for
|
||||
available options. When specifying option names, strip the
|
||||
leading `--`. To set a flag such as
|
||||
`--drive-use-trash`, which does not take a value,
|
||||
set the value to the Boolean `true`.
|
||||
'';
|
||||
example = {
|
||||
bwlimit = "10M";
|
||||
drive-use-trash = "true";
|
||||
};
|
||||
};
|
||||
|
||||
rcloneConfigFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Path to the file containing rclone configuration. This file
|
||||
must contain configuration for the remote specified in this backup
|
||||
set and also must be readable by root. Options set in
|
||||
`rcloneConfig` will override those set in this
|
||||
file.
|
||||
'';
|
||||
};
|
||||
|
||||
timerConfig = mkOption {
|
||||
type = types.attrsOf unitOption;
|
||||
default = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
When to run the backup. See {manpage}`systemd.timer(5)` for details.
|
||||
'';
|
||||
example = {
|
||||
OnCalendar = "00:05";
|
||||
RandomizedDelaySec = "5h";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "root";
|
||||
description = lib.mdDoc ''
|
||||
As which user the backup should run.
|
||||
'';
|
||||
example = "postgresql";
|
||||
};
|
||||
|
||||
extraBackupArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
Extra arguments passed to rustic backup.
|
||||
'';
|
||||
example = [
|
||||
"--exclude-file=/etc/nixos/rustic-ignore"
|
||||
];
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
Extra extended options to be passed to the rustic --option flag.
|
||||
'';
|
||||
example = [
|
||||
"sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'"
|
||||
];
|
||||
};
|
||||
|
||||
backup = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc ''
|
||||
Start backup.
|
||||
'';
|
||||
};
|
||||
|
||||
prune = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = lib.mdDoc ''
|
||||
Start prune.
|
||||
'';
|
||||
};
|
||||
|
||||
initialize = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Create the repository if it doesn't exist.
|
||||
'';
|
||||
};
|
||||
|
||||
initializeOpts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
A list of options for 'rustic init'.
|
||||
'';
|
||||
example = [
|
||||
"--set-version 2"
|
||||
];
|
||||
};
|
||||
|
||||
checkOpts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
A list of options for 'rustic check', which is run after
|
||||
pruning.
|
||||
'';
|
||||
example = [
|
||||
"--with-cache"
|
||||
];
|
||||
};
|
||||
|
||||
pruneOpts = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
A list of options for 'rustic prune', which is run before
|
||||
pruning.
|
||||
'';
|
||||
example = [
|
||||
"--repack-cacheable-only=false"
|
||||
];
|
||||
};
|
||||
|
||||
backupCommandPrefix = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = lib.mdDoc ''
|
||||
Prefix for backup command.
|
||||
'';
|
||||
};
|
||||
|
||||
backupCommandSuffix = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = lib.mdDoc ''
|
||||
Suffix for backup command.
|
||||
'';
|
||||
};
|
||||
|
||||
backupPrepareCommand = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
A script that must run before starting the backup process.
|
||||
'';
|
||||
};
|
||||
|
||||
backupCleanupCommand = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
A script that must run after finishing the backup process.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.rustic-rs;
|
||||
defaultText = literalExpression "pkgs.rustic-rs";
|
||||
description = lib.mdDoc ''
|
||||
Rustic package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
createWrapper = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to generate and add a script to the system path, that has the same environment variables set
|
||||
as the systemd service. This can be used to e.g. mount snapshots or perform other opterations, without
|
||||
having to manually specify most options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.services =
|
||||
mapAttrs'
|
||||
(name: backup:
|
||||
let
|
||||
profile = settingsFormat.generate "${name}.toml" backup.settings;
|
||||
extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions;
|
||||
rusticCmd = "${backup.package}/bin/rustic -P ${lib.strings.removeSuffix ".toml" profile}${extraOptions}";
|
||||
# Helper functions for rclone remotes
|
||||
rcloneAttrToOpt = v: "RCLONE_" + toUpper (builtins.replaceStrings [ "-" ] [ "_" ] v);
|
||||
toRcloneVal = v: if lib.isBool v then lib.boolToString v else v;
|
||||
in
|
||||
nameValuePair "rustic-backups-${name}" ({
|
||||
environment = backup.extraEnvironment // {
|
||||
# not %C, because that wouldn't work in the wrapper script
|
||||
RUSTIC_CACHE_DIR = "/var/cache/rustic-backups-${name}";
|
||||
} // optionalAttrs (backup.rcloneConfigFile != null) {
|
||||
RCLONE_CONFIG = backup.rcloneConfigFile;
|
||||
} // optionalAttrs (backup.rcloneOptions != null) (mapAttrs'
|
||||
(name: value:
|
||||
nameValuePair (rcloneAttrToOpt name) (toRcloneVal value)
|
||||
)
|
||||
backup.rcloneOptions);
|
||||
path = [ config.programs.ssh.package pkgs.rclone ];
|
||||
restartIfChanged = false;
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
script = ''
|
||||
${optionalString (backup.backup) ''
|
||||
${backup.backupCommandPrefix} ${rusticCmd} backup ${concatStringsSep " " backup.extraBackupArgs} ${backup.backupCommandSuffix}
|
||||
''}
|
||||
${optionalString (backup.prune) ''
|
||||
${rusticCmd} forget --prune ${concatStringsSep " " backup.pruneOpts}
|
||||
${rusticCmd} check ${concatStringsSep " " backup.checkOpts}
|
||||
''}
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = backup.user;
|
||||
RuntimeDirectory = "rustic-backups-${name}";
|
||||
CacheDirectory = "rustic-backups-${name}";
|
||||
CacheDirectoryMode = "0700";
|
||||
PrivateTmp = true;
|
||||
} // optionalAttrs (backup.environmentFile != null) {
|
||||
EnvironmentFile = backup.environmentFile;
|
||||
};
|
||||
} // optionalAttrs (backup.initialize || backup.backupPrepareCommand != null) {
|
||||
preStart = ''
|
||||
${optionalString (backup.backupPrepareCommand != null) ''
|
||||
${pkgs.writeScript "backupPrepareCommand" backup.backupPrepareCommand}
|
||||
''}
|
||||
${optionalString (backup.initialize) ''
|
||||
${rusticCmd} init ${concatStringsSep " " backup.initializeOpts} || true
|
||||
''}
|
||||
'';
|
||||
} // optionalAttrs (backup.backupCleanupCommand != null) {
|
||||
postStop = ''
|
||||
${optionalString (backup.backupCleanupCommand != null) ''
|
||||
${pkgs.writeScript "backupCleanupCommand" backup.backupCleanupCommand}
|
||||
''}
|
||||
'';
|
||||
})
|
||||
)
|
||||
config.services.rustic.backups;
|
||||
systemd.timers =
|
||||
mapAttrs'
|
||||
(name: backup: nameValuePair "rustic-backups-${name}" {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = backup.timerConfig;
|
||||
})
|
||||
config.services.rustic.backups;
|
||||
|
||||
# generate wrapper scripts, as described in the createWrapper option
|
||||
environment.systemPackages = lib.mapAttrsToList (name: backup: let
|
||||
profile = settingsFormat.generate "${name}.toml" backup.settings;
|
||||
extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions;
|
||||
rusticCmd = "${backup.package}/bin/rustic -P ${lib.strings.removeSuffix ".toml" profile}${extraOptions}";
|
||||
in pkgs.writeShellScriptBin "rustic-${name}" ''
|
||||
set -a # automatically export variables
|
||||
${lib.optionalString (backup.environmentFile != null) "source ${backup.environmentFile}"}
|
||||
# set same environment variables as the systemd service
|
||||
${lib.pipe config.systemd.services."rustic-backups-${name}".environment [
|
||||
(lib.filterAttrs (_: v: v != null))
|
||||
(lib.mapAttrsToList (n: v: "${n}=${v}"))
|
||||
(lib.concatStringsSep "\n")
|
||||
]}
|
||||
|
||||
exec ${rusticCmd} $@
|
||||
'') (lib.filterAttrs (_: v: v.createWrapper) config.services.rustic.backups);
|
||||
};
|
||||
}
|
@ -62,6 +62,7 @@ with config.deviceSpecific; {
|
||||
# libreoffice
|
||||
obs-studio
|
||||
obs-studio-plugins.obs-vkcapture
|
||||
obsidian
|
||||
pinta
|
||||
qbittorrent
|
||||
sonixd
|
||||
@ -92,6 +93,7 @@ with config.deviceSpecific; {
|
||||
".config/kdeconnect"
|
||||
".config/libreoffice"
|
||||
".config/obs-studio"
|
||||
".config/obsidian"
|
||||
".config/pcmanfm"
|
||||
# ".config/Pinta"
|
||||
".config/qBittorrent"
|
||||
|
@ -123,12 +123,12 @@ in
|
||||
"license.extension" = ".md";
|
||||
"license.year" = "auto";
|
||||
"nix.enableLanguageServer" = true;
|
||||
"nix.formatterPath" = "${pkgs.nixfmt}/bin/nixfmt";
|
||||
"nix.formatterPath" = "${pkgs.nixfmt-rfc-style}/bin/nixfmt";
|
||||
"nix.serverPath" = "${pkgs.nil}/bin/nil";
|
||||
"nix.serverSettings" = {
|
||||
"nil" = {
|
||||
"formatting" = {
|
||||
"command" = ["${pkgs.nixfmt}/bin/nixfmt"];
|
||||
"command" = ["${pkgs.nixfmt-rfc-style}/bin/nixfmt"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -9,16 +9,16 @@ let
|
||||
config = config.nixpkgs.config;
|
||||
localSystem = { inherit system; };
|
||||
};
|
||||
nur = import inputs.nur {
|
||||
nurpkgs = import inputs.nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
};
|
||||
};
|
||||
# nur = import inputs.nur {
|
||||
# nurpkgs = import inputs.nixpkgs {
|
||||
# system = "x86_64-linux";
|
||||
# };
|
||||
# };
|
||||
in
|
||||
with lib; {
|
||||
nixpkgs.overlays = [
|
||||
nur.repos.ataraxiasjel.overlays.default
|
||||
nur.repos.ataraxiasjel.overlays.grub2-argon2
|
||||
inputs.ataraxiasjel-nur.overlays.default
|
||||
inputs.ataraxiasjel-nur.overlays.grub2-argon2
|
||||
inputs.deploy-rs.overlay
|
||||
inputs.hyprland.overlays.default
|
||||
(final: prev:
|
||||
|
@ -1,4 +1,6 @@
|
||||
{ config, inputs, ... }: {
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.authentik ];
|
||||
|
||||
sops.secrets.authentik-env.sopsFile = inputs.self.secretsDir + /home-hypervisor/authentik.yaml;
|
||||
sops.secrets.authentik-ldap.sopsFile = inputs.self.secretsDir + /home-hypervisor/authentik.yaml;
|
||||
sops.secrets.authentik-env.restartUnits = [ "authentik-server.service" "authentik-worker.service" ];
|
||||
|
@ -40,11 +40,14 @@ in {
|
||||
owner = "headscale";
|
||||
restartUnits = [ "headscale.service" ];
|
||||
};
|
||||
systemd.services.headscale.after = lib.mkIf config.services.authentik.enable [
|
||||
"authentik-server.service"
|
||||
"authentik-worker.service"
|
||||
"nginx.service"
|
||||
];
|
||||
systemd.services.headscale = {
|
||||
serviceConfig.TimeoutStopSec = 10;
|
||||
after = lib.mkIf config.services.authentik.enable [
|
||||
"authentik-server.service"
|
||||
"authentik-worker.service"
|
||||
"nginx.service"
|
||||
];
|
||||
};
|
||||
|
||||
persist.state.directories = [ "/var/lib/headscale" ];
|
||||
}
|
@ -1,72 +1,30 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
backend = config.virtualisation.oci-containers.backend;
|
||||
nas-path = "/media/nas/containers";
|
||||
pod-name = "homepage-pod";
|
||||
pod-dns = "192.168.0.1";
|
||||
open-ports = [
|
||||
"127.0.0.1:3000:3000/tcp"
|
||||
];
|
||||
in {
|
||||
virtualisation.oci-containers.containers = {
|
||||
homepage = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/gethomepage/homepage:v0.8.0";
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
};
|
||||
extraOptions = [ "--pod=${pod-name}" ];
|
||||
volumes = [
|
||||
"${nas-path}/homepage/config:/app/config"
|
||||
"${nas-path}/homepage/icons:/app/public/icons"
|
||||
"${nas-path}/homepage/images:/app/public/images"
|
||||
];
|
||||
};
|
||||
docker-proxy = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/tecnativa/docker-socket-proxy:0.1.1";
|
||||
environment = {
|
||||
CONTAINERS = "1";
|
||||
SERVICES = "0";
|
||||
TASKS = "0";
|
||||
POST = "0";
|
||||
};
|
||||
extraOptions = [ "--pod=${pod-name}" ];
|
||||
volumes = [
|
||||
"${nas-path}/homepage/config:/app/config"
|
||||
"${nas-path}/homepage/icons:/app/public/icons"
|
||||
"${nas-path}/homepage/images:/app/public/images"
|
||||
"/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
];
|
||||
};
|
||||
{ config, inputs, ... }: {
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.homepage ];
|
||||
|
||||
services.homepage-dashboard = {
|
||||
enable = true;
|
||||
listenPort = 3000;
|
||||
dataDir = "/srv/homepage";
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${nas-path}/homepage/config 0755 1000 100 -"
|
||||
"d ${nas-path}/homepage/icons 0755 1000 100 -"
|
||||
"d ${nas-path}/homepage/images 0755 1000 100 -"
|
||||
systemd.tmpfiles.rules = let
|
||||
cfg = config.services.homepage-dashboard;
|
||||
in [
|
||||
"d ${cfg.dataDir} 0755 ${cfg.user} ${cfg.group} -"
|
||||
];
|
||||
|
||||
systemd.services."podman-create-${pod-name}" = let
|
||||
portsMapping = lib.concatMapStrings (port: " -p " + port) open-ports;
|
||||
start = pkgs.writeShellScript "create-pod-${pod-name}" ''
|
||||
podman pod exists ${pod-name} || podman pod create -n ${pod-name} ${portsMapping} --dns ${pod-dns}
|
||||
'';
|
||||
stop = "podman pod rm -i -f ${pod-name}";
|
||||
in rec {
|
||||
path = [ pkgs.coreutils config.virtualisation.podman.package ];
|
||||
before = [
|
||||
"${backend}-homepage.service"
|
||||
"${backend}-docker-proxy.service"
|
||||
];
|
||||
requiredBy = before;
|
||||
partOf = before;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
ExecStart = start;
|
||||
ExecStop = stop;
|
||||
virtualisation.oci-containers.containers.docker-proxy = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/tecnativa/docker-socket-proxy:0.1.1";
|
||||
environment = {
|
||||
CONTAINERS = "1";
|
||||
SERVICES = "0";
|
||||
TASKS = "0";
|
||||
POST = "0";
|
||||
};
|
||||
ports = [ "127.0.0.1:2375:2375/tcp" ];
|
||||
volumes = [
|
||||
"/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
];
|
||||
};
|
||||
}
|
@ -13,6 +13,8 @@ let
|
||||
restartUnits = [ "kes.service" ];
|
||||
};
|
||||
in {
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.kes ];
|
||||
|
||||
sops.secrets.minio-credentials = minio-secret;
|
||||
sops.secrets.kes-vault-env = kes-secret;
|
||||
sops.secrets.kes-key = kes-secret;
|
||||
|
@ -5,6 +5,8 @@
|
||||
sopsFile = inputs.self.secretsDir + /home-hypervisor/ocis.yaml;
|
||||
restartUnits = [ "ocis-server.service" ];
|
||||
};
|
||||
imports = [ inputs.ataraxiasjel-nur.nixosModules.ocis ];
|
||||
|
||||
services.ocis = {
|
||||
enable = true;
|
||||
configDir = "/var/lib/ocis";
|
||||
|
@ -24,10 +24,16 @@ in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
partOf = [ "vault.service" ];
|
||||
after = [ "vault.service" ];
|
||||
path = [ pkgs.curl ];
|
||||
path = [ pkgs.curl pkgs.jq ];
|
||||
script = ''
|
||||
set -aeuo pipefail
|
||||
set -a
|
||||
source ${config.sops.secrets.vault-keys-env.path}
|
||||
while true; do
|
||||
initialized=$(curl -s ${api-addr}/v1/sys/health | jq -r '.initialized')
|
||||
[[ "$initialized" = "true" ]] && break
|
||||
echo "Vault has not been initialized yet. Will try again after 5 seconds." >&2
|
||||
sleep 5
|
||||
done
|
||||
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY1\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
||||
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY2\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
||||
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY3\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user