Files
home-manager/modules/programs/docker-cli.nix
Austin Horstman 6406966663 docker-cli: warn that settings are world-readable
config.json is generated in the world-readable Nix store, but the
description did not warn against registry credentials or proxy
passwords. Point at Docker credential stores instead, note that docker
login still reports an error when it adds a registry to the read-only
file, and mention the helper's own store command. Also close the
unterminated link to the config.json reference.
2026-09-25 13:01:17 -05:00

134 lines
4.0 KiB
Nix

{
lib,
pkgs,
config,
...
}:
let
inherit (lib)
mkIf
mkEnableOption
mkOption
;
cfg = config.programs.docker-cli;
jsonFormat = pkgs.formats.json { };
in
{
meta.maintainers = [
lib.maintainers.friedrichaltheide
lib.hm.maintainers.will-lol
];
options.programs.docker-cli = {
enable = mkEnableOption "management of docker client config";
configDir = mkOption {
type = lib.types.str;
apply = p: lib.removePrefix "${config.home.homeDirectory}/" p;
default =
if config.xdg.enable && lib.versionAtLeast config.home.stateVersion "26.05" then
"${config.xdg.configHome}/docker"
else
".docker";
defaultText = lib.literalExpression ''
if config.xdg.enable && lib.versionAtLeast config.home.stateVersion "26.05" then
"$XDG_CONFIG_HOME/docker"
else
".docker"
'';
example = lib.literalExpression "\${config.xdg.configHome}/docker";
description = "Directory to store configuration and state. This also sets $DOCKER_CONFIG.";
};
contexts = mkOption {
type = lib.types.attrsOf (
lib.types.submodule (
{ name, ... }:
{
freeformType = jsonFormat.type;
options = {
Name = mkOption {
type = lib.types.str;
readOnly = true;
description = "Name of the Docker context. Defaults to the attribute name (the <name> in programs.docker-cli.contexts.<name>). Overriding requires lib.mkForce.";
};
};
config.Name = name;
}
)
);
default = { };
example = lib.literalExpression ''
{
example = {
Metadata = { Description = "example1"; };
Endpoints.docker.Host = "unix://example2";
};
}
'';
description = ''
Attribute set of Docker context configurations. Each attribute name becomes the context Name; overriding requires lib.mkForce. See:
<https://docs.docker.com/engine/manage-resources/contexts/
'';
};
settings = mkOption {
inherit (jsonFormat) type;
default = { };
example = lib.literalExpression ''
{
"proxies" = {
"default" = {
"httpProxy" = "http://proxy.example.org:3128";
"httpsProxy" = "http://proxy.example.org:3128";
"noProxy" = "localhost";
};
};
'';
description = ''
Available configuration options for the Docker CLI see:
<https://docs.docker.com/reference/cli/docker/#docker-cli-configuration-file-configjson-properties>
These settings are written to the world-readable Nix store, so avoid
putting registry credentials or proxy passwords here. For registry
credentials, Docker's `credsStore` or `credHelpers` settings can keep
them in a credential helper instead; see
[Docker credential stores](https://docs.docker.com/reference/cli/docker/login/#credential-stores).
Because Home Manager links {file}`config.json` read-only,
`docker login` still reports an error when it adds a registry to
that file, even after the credential helper has stored the
credential. You can store the credential with the helper's own
`store` command instead.
'';
};
};
config = mkIf cfg.enable {
home = {
sessionVariables = {
DOCKER_CONFIG = "${config.home.homeDirectory}/${cfg.configDir}";
};
file = {
"${cfg.configDir}/config.json" = {
source = jsonFormat.generate "config.json" cfg.settings;
};
}
// lib.mapAttrs' (
_n: ctx:
let
path = "${cfg.configDir}/contexts/meta/${builtins.hashString "sha256" ctx.Name}/meta.json";
in
{
name = path;
value = {
source = jsonFormat.generate "config.json" ctx;
};
}
) cfg.contexts;
};
};
}