aboutsummaryrefslogtreecommitdiff
path: root/nixos/serverModules
diff options
context:
space:
mode:
authorspl3g <spleefer6@yandex.ru>2025-08-22 22:24:50 +0500
committerspl3g <spleefer6@yandex.ru>2025-08-22 22:38:35 +0500
commitc087d476f03b9e94a879ab1fa752ffe90de3e7f9 (patch)
tree1b41316e76715648442654bd97b0f7cbca9714b5 /nixos/serverModules
parentc7117141d2f42f5be5006d07e6d6476238fb96e6 (diff)
feat: add server modules
Diffstat (limited to 'nixos/serverModules')
-rw-r--r--nixos/serverModules/files.nix59
-rw-r--r--nixos/serverModules/gonic.nix88
-rw-r--r--nixos/serverModules/nfs.nix113
-rw-r--r--nixos/serverModules/nginx.nix136
4 files changed, 396 insertions, 0 deletions
diff --git a/nixos/serverModules/files.nix b/nixos/serverModules/files.nix
new file mode 100644
index 0000000..037d149
--- /dev/null
+++ b/nixos/serverModules/files.nix
@@ -0,0 +1,59 @@
+{ config, lib, ... }:
+with lib;
+let
+ cfg = config.filesDir;
+in
+{
+ options = {
+ filesDir = {
+ enable = mkEnableOption "Enable the creation of a main files directory and nfs binds for it.";
+ mainDir = mkOption {
+ type = types.str;
+ default = "/srv/files";
+ description = ''
+ The main file dir.
+ '';
+ };
+ subPaths = mkOption {
+ type = types.listOf (types.submodule {
+ options = {
+ path = mkOption {
+ type = types.str;
+ };
+
+ group = mkOption {
+ type = types.str;
+ };
+ };
+ });
+ default = [];
+ description = ''
+ Subpaths to create under the files dir.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.tmpfiles.rules = [
+ "d ${cfg.mainDir} 0770 files files"
+ ] ++ (map (dir: "d ${cfg.mainDir}/${dir.path} 0770 files ${dir.group}") cfg.subPaths);
+
+ users =
+ let
+ extraGroups = (map (dir: dir.group) cfg.subPaths);
+ in {
+ groups = {
+ files = {};
+ } // genAttrs extraGroups (group: {});
+
+ users.files = {
+ isNormalUser = true;
+ group = "files";
+ home = cfg.mainDir;
+ homeMode = "770";
+ inherit extraGroups;
+ };
+ };
+ };
+}
diff --git a/nixos/serverModules/gonic.nix b/nixos/serverModules/gonic.nix
new file mode 100644
index 0000000..526d79e
--- /dev/null
+++ b/nixos/serverModules/gonic.nix
@@ -0,0 +1,88 @@
+{ config, lib, ... }:
+with lib;
+let
+ cfg = config.gonic;
+in
+{
+ options = {
+ gonic = {
+ enable = mkEnableOption "enable gonic configuration";
+
+ listenAddr = mkOption {
+ type = types.str;
+ default = "127.0.0.1:4747";
+ description = ''
+ Address that gonic will listen on.
+ '';
+ };
+
+ extraGroups = mkOption {
+ type = types.listOf (types.str);
+ default = [];
+ description = ''
+ Additional groups for gonic.
+ '';
+ };
+
+ musicPaths = mkOption {
+ type = types.listOf (types.str);
+ description = ''
+ Directories with music in it.
+ '';
+ };
+
+ podcastsPath = mkOption {
+ type = types.str;
+ default = "${cfg.stateDir}/podcasts";
+ description = ''
+ Directory for podcasts.
+ '';
+ };
+
+ playlistsPath = mkOption {
+ type = types.str;
+ default = "${cfg.stateDir}/playlists";
+ description = ''
+ Directory for playlists.
+ '';
+ };
+
+ stateDir = mkOption {
+ type = types.str;
+ default = "/var/lib/gonic";
+ description = ''
+ A directory where gonic will keep their files.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ nixpkgs.overlays = [
+ (final: prev: {
+ ffmpeg = prev.ffmpeg-headless;
+ })
+ ];
+
+ systemd.services.gonic.serviceConfig = {
+ SupplementaryGroups = cfg.extraGroups;
+ };
+
+ systemd.tmpfiles.rules = [
+ "d ${cfg.stateDir} 0755 nobody nogroup"
+ "d ${cfg.podcastsPath} 0755 nobody nogroup"
+ "d ${cfg.playlistsPath} 0755 nobody nogroup"
+ ];
+
+ services.gonic = {
+ enable = true;
+ settings = {
+ listen-addr = cfg.listenAddr;
+ music-path = cfg.musicPaths;
+ playlists-path = [cfg.podcastsPath];
+ podcast-path = [cfg.playlistsPath];
+ db-path = ["${cfg.stateDir}/gonic.db"];
+ };
+ };
+ };
+}
diff --git a/nixos/serverModules/nfs.nix b/nixos/serverModules/nfs.nix
new file mode 100644
index 0000000..5a88697
--- /dev/null
+++ b/nixos/serverModules/nfs.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+with lib;
+let
+ cfg = config.nfs;
+in
+{
+ options = {
+ nfs = {
+ server = mkOption {
+ description = ''
+ NFS server configuration.
+ '';
+ type = types.submodule {
+ options = {
+ enable = mkEnableOption "Enable nfs server";
+ exportsPath = mkOption {
+ type = types.str;
+ default = "/export";
+ description = ''
+ A path to the dir, where exports will be binded.
+ '';
+ };
+
+ defaultExportIps = mkOption {
+ type = types.listOf (types.str);
+ description = ''
+ A list of ip addresses, that will be used as default in exportDirs
+ '';
+ };
+
+ defaultExportParams = mkOption {
+ type = types.str;
+ default = "rw,nohide,insecure,no_subtree_check";
+ description = ''
+ Params, that will be used as default in exportDirs
+ '';
+ };
+
+ exportDirs = mkOption {
+ description = ''
+ A list of directories to export.
+ '';
+ type = types.listOf (types.submodule {
+ options = {
+ path = mkOption {
+ type = types.str;
+ description = ''
+ A path to the directory to export.
+ '';
+ };
+ exportPath = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ A path that will be binded to the export directory in the exportsPath.
+ '';
+ };
+ ips = mkOption {
+ type = types.listOf (types.str);
+ default = cfg.server.defaultExportIps;
+ description = ''
+ A list of ip addresses to export the dir to.
+ '';
+ };
+ params = mkOption {
+ type = types.str;
+ default = cfg.server.defaultExportParams;
+ description = ''
+ Params for the ip addresses.
+ '';
+ };
+ };
+ });
+ };
+ };
+ };
+ };
+ };
+ };
+
+ config = mkIf cfg.server.enable {
+ services.nfs.server = {
+ enable = true;
+ exports = "${cfg.server.exportsPath} ${concatMapStrings (ip: "${ip}(rw,fsid=0,no_subtree_check) ") cfg.server.defaultExportIps}\n"
+ + concatMapStrings
+ (dir:
+ let
+ ips = concatMapStrings (ip: "${ip}(${dir.params}) ") dir.ips;
+ exportPath = if dir.exportPath != "" then dir.exportPath else
+ baseNameOf dir.path;
+ in "${cfg.server.exportsPath}/${exportPath} ${ips}\n")
+ cfg.server.exportDirs;
+ };
+
+ systemd.tmpfiles.rules = [
+ "d ${cfg.server.exportsPath} 0744 nobody nogroup"
+ ];
+
+ fileSystems = listToAttrs (map (exportDir:
+ let
+ exportPath = if exportDir.exportPath != "" then exportDir.exportPath else
+ baseNameOf exportDir.path;
+ fullExportPath = "${cfg.server.exportsPath}/${exportPath}";
+ in
+ {
+ name = fullExportPath;
+ value = {
+ device = exportDir.path;
+ options = ["bind"];
+ };
+ }) cfg.server.exportDirs);
+ };
+}
diff --git a/nixos/serverModules/nginx.nix b/nixos/serverModules/nginx.nix
new file mode 100644
index 0000000..9e249d9
--- /dev/null
+++ b/nixos/serverModules/nginx.nix
@@ -0,0 +1,136 @@
+{ pkgs, config, lib, ... }:
+with lib;
+let
+ vhostOptions = import (pkgs.path + "/nixos/modules/services/web-servers/nginx/vhost-options.nix");
+ locationOptions = import (pkgs.path + "/nixos/modules/services/web-servers/nginx/location-options.nix");
+ nginxOptions = import (pkgs.path + "/nixos/modules/services/web-servers/nginx/default.nix");
+ cfg = config.nginx;
+in
+{
+ options.nginx = {
+ enable = mkEnableOption "Enable nginx";
+
+ domain = mkOption {
+ type = types.str;
+ description = ''
+ Domain to use with subdomains
+ '';
+ };
+
+ recommendedProxySettings = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Enables global recommended proxy settings
+ '';
+ };
+
+ subdomains = mkOption {
+ type = types.attrsOf (types.submodule (locationOptions { inherit config lib; }));
+ description = ''
+ Subdomains with nginx virtualHosts configuration
+ '';
+ };
+
+ extraVirtualHosts = mkOption {
+ type = types.attrsOf (types.submodule (vhostOptions { inherit config lib; }));
+ default = {};
+ };
+
+ home = {
+ virtualHosts = mkOption {
+ type = types.attrsOf (types.submodule (vhostOptions { inherit config lib; }));
+ default = {};
+ description = ''
+ Virtual hosts from another nginx configuration, that will be used to decrypt ssl and forward traffic to another server.
+ Make sure that the connection between the two is secure.
+ '';
+ };
+
+ subdomains = mkOption {
+ type = types.attrsOf (types.submodule (locationOptions { inherit config lib; }));
+ default = {};
+ description = ''
+ Subdomains from another nginx configuration, that will be used to decrypt ssl and forward traffic to another server.
+ Make sure that the connection between the two is secure.
+ '';
+ };
+
+ domain = mkOption {
+ type = types.str;
+ default = cfg.domain;
+ description = ''
+ Home domain, if no domain provided, the current will be used;
+ '';
+ };
+
+ url = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ Url that requests would be passed to;
+ '';
+ };
+ };
+
+ acme = {
+ enable = mkEnableOption "enable acme certs";
+ email = mkOption {
+ type = types.str;
+ default = "notspl3g+acme@duck.com";
+ };
+ };
+
+ extraConfig = mkOption {
+ type = types.attrsOf (types.submodule nginxOptions);
+ default = {};
+ description = ''
+ Extra nginx config.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ security.acme = mkIf cfg.acme.enable {
+ acceptTerms = true;
+ defaults.email = cfg.acme.email;
+ };
+
+ users.groups.nginx = mkIf cfg.acme.enable {};
+ users.users.nginx = mkIf cfg.acme.enable {
+ group = "nginx";
+ extraGroups = [ "acme" ];
+ isSystemUser = true;
+ };
+ services.nginx =
+ let
+ ssl = {
+ forceSSL = cfg.acme.enable;
+ enableACME = cfg.acme.enable;
+ };
+
+ makeVhosts = (domain: subdomains:
+ lib.concatMapAttrs
+ (name: value: { ${name + "." + domain} = { locations."/" = value; } // ssl; })
+ subdomains);
+
+ homeRoutes = (homeVirtualHosts: homeUrl:
+ builtins.mapAttrs
+ (name: value: {
+ locations."/" = value.locations."/" // {
+ proxyPass = homeUrl;
+ recommendedProxySettings = true;
+ };
+ } // ssl)
+ homeVirtualHosts);
+
+ vhosts = (makeVhosts cfg.domain cfg.subdomains);
+ homeVhosts = (homeRoutes ((makeVhosts (cfg.home.domain) cfg.home.subdomains) // cfg.home.virtualHosts) cfg.home.url);
+ in {
+ enable = true;
+ recommendedProxySettings = cfg.recommendedProxySettings;
+
+ virtualHosts = vhosts // homeVhosts // cfg.extraVirtualHosts;
+ } // cfg.extraConfig;
+ };
+}