nixos/modules/services/docker.nix
2023-09-01 21:05:26 +08:00

104 lines
4.1 KiB
Nix

inputs:
{
options.nixos.services.docker = let inherit (inputs.lib) mkOption types; in
{
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
[
types.ints.unsigned
types.submodule (inputs: { options =
{
hostIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
hostPort = mkOption { type = types.ints.unsigned; };
containerPort = mkOption { type = types.ints.unsigned; };
protocol = mkOption { type = types.enum [ "tcp" "udp" ]; default = "tcp"; };
};})
]);
default = [];
};
environmentFile = mkOption { type = types.oneOf [ types.bool types.nonEmptyStr ]; default = false; };
};}));
default = {};
};
config =
let
inherit (inputs.lib) mkMerge mkIf;
inherit (builtins) listToAttrs map concatLists;
inherit (inputs.localLib) attrsToList;
inherit (inputs.config.nixos.services) docker;
in mkMerge
[
{
virtualisation.oci-containers.containers = listToAttrs (map
(container:
{
name = "${container.name}";
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 ];
};
})
(attrsToList docker));
systemd.services = listToAttrs (concatLists (map
(container:
[
{
name = "docker-${container.value.user}-daemon";
value =
{
wantedBy = [ "multi-user.target" ];
inherit (inputs.systemd.user.services.docker) description path;
serviceConfig = inputs.systemd.user.services.docker.serviceConfig //
{
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";
};
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;
})
];
}