This commit is contained in:
2023-09-18 08:22:42 +08:00
parent 7243090020
commit 6b90d5068b
6 changed files with 166 additions and 78 deletions

View File

@@ -211,6 +211,7 @@
nginx = { enable = true; transparentProxy.enable = false; };
misskey = { enable = true; hostname = "xn--qbtm095lrg0bfka60z.chn.moe"; };
misskey-proxy."xn--qbtm095lrg0bfka60z.chn.moe" = {};
huginn.enable = true;
};
bugs =
[

View File

@@ -19,7 +19,8 @@ inputs:
./sshd.nix
./vaultwarden.nix
./frp.nix
# ./docker.nix
./docker.nix
./huginn.nix
];
options.nixos.services = let inherit (inputs.lib) mkOption types; in
{

View File

@@ -1,13 +1,11 @@
inputs:
{
options.nixos.services.docker = let inherit (inputs.lib) mkOption types; in
options.nixos.services.docker = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.attrsOf (types.submodule (inputs: { options =
{
user = mkOption { type = types.nonEmptyStr; default = inputs.config._module.args.name; };
image = mkOption { type = types.package; };
imageName =
mkOption { type = types.nonEmptyStr; default = with inputs.image; (imageName + ":" + imageTag); };
ports = mkOption
{
type = types.listOf (types.oneOf
@@ -29,75 +27,104 @@ inputs:
};
config =
let
inherit (inputs.lib) mkMerge mkIf;
inherit (builtins) listToAttrs map concatLists;
inherit (inputs.lib) mkIf;
inherit (builtins) listToAttrs map;
inherit (inputs.localLib) attrsToList;
inherit (inputs.config.nixos.services) docker;
in mkMerge
[
users = inputs.lib.lists.unique (map (container: container.value.user) (attrsToList docker));
# users = map
# (user: builtins.filter (container: container.user == user) (builtins.attrValues docker))
# (inputs.lib.lists.unique (map (container: container.value.user) (attrsToList docker)));
in mkIf (docker != {})
{
systemd.tmpfiles.rules = [ "d /run/docker-rootless 0755 root root" ];
nixos =
{
virtualisation.oci-containers.containers = listToAttrs (map
(container:
virtualization.docker.enable = true;
users.linger = users;
};
users =
{
users = listToAttrs (map
(user:
{
name = "${container.name}";
name = user;
value =
{
image = container.value.imageName;
imageFile = container.value.image;
ports = map
(port:
(
if builtins.typeOf port == "int" then "127.0.0.1::${toString port}"
else ("${port.value.hostIp}:${toString port.value.hostPort}"
+ ":${toString port.value.containerPort}/${port.value.protocol}")
))
container.value.ports;
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
environmentFiles =
if builtins.typeOf container.value.environmentFile == "bool" && container.value.environmentFile
then [ inputs.config.sops.templates."${container.name}/env".path ]
else if builtins.typeOf container.value.environmentFile == "bool" then []
else [ container.value.environmentFile ];
isSystemUser = true;
group = user;
autoSubUidGidRange = true;
home = "/run/docker-rootless/${user}";
createHome = true;
};
})
(attrsToList docker));
systemd.services = listToAttrs (concatLists (map
(container:
[
users);
groups = listToAttrs (map (user: { name = user; value = {}; }) users);
};
home-manager.users = listToAttrs (map
(user:
{
name = user;
value.config.systemd.user.services = listToAttrs (map
(container:
{
name = "docker-${container.value.user}-daemon";
inherit (container) name;
value =
{
wantedBy = [ "multi-user.target" ];
inherit (inputs.systemd.user.services.docker) description path;
serviceConfig = inputs.systemd.user.services.docker.serviceConfig //
Unit =
{
User = container.value.user;
Group = container.value.user;
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
ExecStart = inputs.systemd.user.services.docker.serviceConfig.ExecStart
+ " -H unix:///var/run/docker-rootless/${container.value.user}.sock";
After = [ "dbus.socket" ];
Wants = [ "dbus.socket" ];
};
Install.WantedBy = [ "default.target" ];
Service =
{
Type = "simple";
RemainAfterExit = true;
ExecStart = inputs.pkgs.writeShellScript "docker-${container.name}.start"
''
docker rm -f ${container.name} || true
echo "loading image"
docker load -i ${container.value.image}
echo "load finish"
docker image ls
${
builtins.concatStringsSep " \\\n"
(
[
"docker run --rm --name=${container.name}"
"--add-host=host.docker.internal:host-gateway"
]
++ (
if (builtins.typeOf container.value.environmentFile) == "string"
then [ "--env-file ${container.value.environmentFile}" ]
else if container.value.environmentFile
then [ "--env-file ${inputs.config.sops.templates."${container.name}.env".path}" ]
else []
)
++ (map
(port: "-p ${port}")
(map
(port:
if builtins.typeOf port == "int" then toString port
else "${port.value.hostIp}:${toString port.value.hostPort}"
+ ":${toString port.value.containerPort}/${port.value.protocol}"
)
container.value.ports))
++ [ "${container.value.image.imageName}:${container.value.image.imageTag}" ]
)
}
'';
ExecStop = inputs.pkgs.writeShellScript "docker-${container.name}.stop"
''
docker stop ${container.name}
docker system prune --volumes --force
'';
};
unitConfig = { inherit (inputs.systemd.user.services.docker.unitConfig) StartLimitInterval; };
};
}
{
name = "docker-${container.name}";
value =
{
requires = [ "docker-${container.value.user}-daemon.service" ];
after = [ "docker-${container.value.user}-daemon.service" ];
environment.DOCKER_HOST = "unix:///var/run/docker-rootless/${container.value.user}.sock";
serviceConfig = { User = container.value.user; Group = container.value.user; };
};
}
])
(attrsToList docker)));
}
(mkIf (docker != {})
{
systemd.tmpfiles.rules = [ "d /var/run/docker-rootless 0777" ];
nixos.virtualization.docker.enable = true;
})
];
})
(builtins.filter (container: container.value.user == user) (attrsToList docker)));
})
users);
};
}

View File

@@ -1,23 +1,58 @@
inputs:
{
options.nixos.services.huginn.enable = inputs.lib.mkOption { type = inputs.lib.types.bool; default = false; };
config = inputs.lib.mkIf inputs.config.nixos.services.huginn.enable
options.nixos.services.huginn = let inherit (inputs.lib) mkOption types; in
{
nixos.services =
enable = mkOption { type = types.bool; default = false; };
};
config =
let
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) huginn;
inherit (builtins) listToAttrs;
in mkIf huginn.enable
{
docker.huginn =
nixos.services =
{
image = inputs.pkgs.dockerTools.pullImage
docker.huginn =
{
imageName = "huginn/huginn";
imageDigest = "sha256:dbe871597d43232add81d1adfc5ad9f5cf9dcb5e1f1ba3d669598c20b96ab6c1";
sha256 = "0ls97k8ic7w5j54jlpwh8rrvj1y4pl4106j9pyap105r6p7dziiz";
finalImageName = "huginn/huginn";
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
image = inputs.pkgs.dockerTools.pullImage
{
imageName = "huginn/huginn";
imageDigest = "sha256:dbe871597d43232add81d1adfc5ad9f5cf9dcb5e1f1ba3d669598c20b96ab6c1";
sha256 = "sha256-P8bfzjW5gHCVv0kaEAi9xAe5c0aQXypJkYUfFtE8SVM=";
finalImageName = "huginn/huginn";
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
};
ports = [ 3000 ];
environmentFile = true;
};
ports = [ 3000 ];
environmentFile = true;
# postgresql = { enable = true; instances.huginn = {}; };
};
sops =
{
templates."huginn.env" =
{
content = let placeholder = inputs.config.sops.placeholder; in "";
# ''
# MYSQL_PORT_3306_TCP_ADDR=host.docker.internal
# HUGINN_DATABASE_NAME=huginn
# HUGINN_DATABASE_USERNAME=huginn
# HUGINN_DATABASE_PASSWORD=${placeholder."postgresql/huginn"}
# DOMAIN=huginn.chn.moe
# RAILS_ENV=production
# FORCE_SSL=true
# INVITATION_CODE=${placeholder."huginn/invitation_code"}
# SMTP_DOMAIN=mail.chn.moe
# SMTP_USER_NAME=bot@chn.moe
# SMTP_PASSWORD="${placeholder."mail/bot"}"
# SMTP_SERVER=mail.chn.moe
# SMTP_SSL=true
# EMAIL_FROM_ADDRESS=bot@chn.moe
# TIMEZONE=Beijing
# '';
owner = inputs.config.users.users.huginn.name;
};
# secrets = listToAttrs (map (secret: { name = secret; value = {}; }) [ "huginn/invitation_code" "mail/bot" ]);
};
};
};
}

View File

@@ -41,9 +41,12 @@ inputs:
"${impermanence.root}" =
{
hideMounts = true;
directories = []
++ (if inputs.config.services.xserver.displayManager.sddm.enable then
[{ directory = "/var/lib/sddm"; user = "sddm"; group = "sddm"; mode = "0700"; }] else []);
directories =
[
"/var/lib/systemd/linger"
]
++ (if inputs.config.services.xserver.displayManager.sddm.enable then
[{ directory = "/var/lib/sddm"; user = "sddm"; group = "sddm"; mode = "0700"; }] else []);
};
"${impermanence.nodatacow}" =
{

View File

@@ -201,6 +201,7 @@ inputs:
{
users = mkOption { type = types.listOf (types.enum (builtins.attrNames allUsers)); default = [ "root" "chn" ]; };
sharedModules = mkOption { type = types.listOf types.anything; default = []; };
linger = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
};
config =
let
@@ -210,6 +211,26 @@ inputs:
in mkMerge
[
(mkMerge (map (user: mkIf (builtins.elem user users.users) allUsers.${user}) (attrNames allUsers)))
{
system.activationScripts.linger = builtins.concatStringsSep "\n" (map
(user: "${inputs.pkgs.systemd}/bin/loginctl enable-linger ${user}") users.linger);
}
# {
# fileSystems."/var/lib/systemd/linger" =
# {
# device = (inputs.pkgs.stdenv.mkDerivation
# {
# name = "systemd-linger";
# phases = [ "installPhase" ];
# installPhase = builtins.concatStringsSep "\n"
# (
# [ "mkdir -p $out" ]
# ++ (map (user: "touch $out/${user}") users.linger)
# );
# }).outPath;
# options = [ "bind" "private" "x-gvfs-hide" ];
# };
# }
];
}
@@ -254,4 +275,4 @@ inputs:
# ".viminfo"
# ".zsh_history"
# ];
# };
# };