diff options
| author | spl3g <spleefer6@yandex.ru> | 2025-08-22 22:24:50 +0500 |
|---|---|---|
| committer | spl3g <spleefer6@yandex.ru> | 2025-08-22 22:38:35 +0500 |
| commit | c087d476f03b9e94a879ab1fa752ffe90de3e7f9 (patch) | |
| tree | 1b41316e76715648442654bd97b0f7cbca9714b5 /nixos/serverModules | |
| parent | c7117141d2f42f5be5006d07e6d6476238fb96e6 (diff) | |
feat: add server modules
Diffstat (limited to 'nixos/serverModules')
| -rw-r--r-- | nixos/serverModules/files.nix | 59 | ||||
| -rw-r--r-- | nixos/serverModules/gonic.nix | 88 | ||||
| -rw-r--r-- | nixos/serverModules/nfs.nix | 113 | ||||
| -rw-r--r-- | nixos/serverModules/nginx.nix | 136 |
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; + }; +} |
