{ 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 in programs.docker-cli.contexts.). 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: 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; }; }; }