feat: Add module for self-hosted cinny

This commit is contained in:
ulic-youthlic 2026-02-19 13:34:09 +08:00
parent 93dad25698
commit 415e9862b6
Signed by: youthlic
GPG key ID: 63E86C3C14A0D721
4 changed files with 141 additions and 0 deletions

View file

@ -3,6 +3,7 @@
lib,
inputs,
outputs,
config,
...
}: {
imports =
@ -39,6 +40,19 @@
};
};
programs = {
miniserve = {
enable = true;
apps = let
cinny-template = config.youthlic.programs.miniserve.templates.cinny;
in {
cinny-1 = cinny-template {
port = 9093;
};
cinny-2 = cinny-template {
port = 9094;
};
};
};
bash.enable = true;
guix.enable = true;
dae.enable = true;

View file

@ -0,0 +1,27 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.youthlic.programs.caddy.cinny;
caddy-cfg = config.youthlic.programs.caddy;
in {
options = {
youthlic.programs.caddy.cinny = {
enable = lib.mkEnableOption "caddy.cinny";
};
};
config = lib.mkIf (cfg.enable && caddy-cfg.enable) {
services.caddy.virtualHosts = {
"cinny.${caddy-cfg.baseDomain}" = {
extraConfig = ''
root * ${pkgs.cinny}
encode gzip zstd
try_files {path} /index.html
file_server
'';
};
};
};
}

View file

@ -0,0 +1,16 @@
{
pkgs,
lib,
...
}: {
config.youthlic.programs.miniserve.templates.cinny = {port, ...} @ args:
{
inherit port;
directory = args.cinny or (toString pkgs.cinny);
defaultIndex = "index.html";
isSpa = true;
}
// (lib.optionalAttrs (args ? interface) {
inherit (args) interface;
});
}

View file

@ -0,0 +1,84 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.youthlic.programs.miniserve;
in {
imports = lib.youthlic.loadImports ./.;
options = {
youthlic.programs.miniserve = {
enable = lib.mkEnableOption "miniserve";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.miniserve;
};
templates = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = {};
};
apps = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({...}: {
options = {
port = lib.mkOption {
type = lib.types.port;
};
interface = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
};
isSpa = lib.mkEnableOption "is spa";
directory = lib.mkOption {
type = lib.types.either lib.types.package lib.types.path;
};
defaultIndex = lib.mkOption {
type = lib.types.str;
default = "index.html";
};
};
}));
default = {};
};
};
};
config = lib.mkIf (cfg.enable && (cfg.apps != {})) {
systemd.services =
lib.concatMapAttrs (name: value: {
"miniserve-${name}" = {
description = ''
miniserve for ${name}
'';
after = ["network-online.target"];
wants = ["network-online.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
ExecStart = ''
${lib.getExe cfg.package} ${lib.optionalString value.isSpa "--spa"} --index ${value.directory}/${value.defaultIndex} --port ${toString value.port} --interfaces ${value.interface} ${value.directory}
'';
IPAccounting = "yes";
IPAddressAllow = value.interface;
IPAddressDeny = "any";
DynamicUser = "yes";
PrivateTmp = "yes";
PrivateUsers = "yes";
PrivateDevices = "yes";
NoNewPrivileges = true;
ProtectSystem = "strict";
ProtectHome = "yes";
ProtectClock = "yes";
ProtectControlGroups = "yes";
ProtectKernelLogs = "yes";
ProtectKernelModules = "yes";
ProtectKernelTunables = "yes";
ProtectProc = "invisible";
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
"CAP_DAC_READ_SEARCH"
];
};
};
})
cfg.apps;
};
}