Skip to content

Use `mkFlake` in a consuming repo

Use kixpkgs.lib.mkFlake in the repository that owns your cluster definitions. It exposes the cluster outputs that the Kix CLI discovers.

Create a flake.nix and declare nixpkgs and kixpkgs:

flake.nix
{
description = "Application infrastructure";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
kixpkgs.url = "github:kix-run/kixpkgs";
kixpkgs.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = inputs: inputs.kixpkgs.lib.mkFlake {
inherit inputs;
clusters.production = ./clusters/production.nix;
};
}

Following the same nixpkgs input keeps package evaluation on one nixpkgs revision.

The examples repository registers each cluster by name:

flake.nix (L24–L61)
outputs =
inputs:
inputs.kixpkgs.lib.mkFlake {
inherit inputs;
clusters = {
"02-hello-world" = ./tutorials/02-hello-world/cluster.nix;
"06-service-dep" = ./tutorials/06-service-dep/cluster.nix;
"08-namespace-deps" = ./tutorials/08-namespace-deps/cluster.nix;
"09-typed-options" = ./tutorials/09-typed-options/cluster.nix;
"10-reuse-packages" = ./tutorials/10-reuse-packages/cluster.nix;
"19-scorecards" = ./tutorials/19-scorecards/cluster.nix;
"how-to-application" = ./how-to/application/cluster.nix;
"how-to-adoption" = ./how-to/adoption/cluster.nix;
"how-to-stateful-migration" = ./how-to/adoption/stateful-before-cluster.nix;
"how-to-adoption-takeover" = ./how-to/adoption/takeover-cluster.nix;
"how-to-helm-bridge" = ./how-to/adoption/helm-bridge-cluster.nix;
"how-to-auto-instantiation" = ./how-to/auto-instantiation/cluster.nix;
"how-to-composition" = ./how-to/composition/cluster.nix;
"how-to-fragments" = ./how-to/composition/fragments-cluster.nix;
"how-to-multi-env" = ./how-to/composition/multi-env-cluster.nix;
"how-to-package-storage" = ./how-to/package-stacks/storage-cluster.nix;
"how-to-package-python" = ./how-to/package-stacks/python-cluster.nix;
"how-to-package-stackgres" = ./how-to/package-stacks/stackgres-cluster.nix;
"how-to-package-monitoring" = ./how-to/package-stacks/monitoring-cluster.nix;
"how-to-package-cilium" = ./how-to/package-stacks/cilium-cluster.nix;
"how-to-package-valkey" = ./how-to/package-stacks/valkey-cluster.nix;
"how-to-package-velero" = ./how-to/package-stacks/velero-cluster.nix;
"how-to-package-victoria-metrics" = ./how-to/package-stacks/victoria-metrics-cluster.nix;
"how-to-platform-gateway" = ./how-to/platform/gateway-cluster.nix;
"how-to-platform-hostpath" = ./how-to/platform/hostpath-cluster.nix;
"how-to-platform-ingress" = ./how-to/platform/ingress-cluster.nix;
"how-to-platform-monitoring" = ./how-to/platform/monitoring-cluster.nix;
"how-to-platform-network-policy" = ./how-to/platform/network-policy-cluster.nix;
"how-to-platform-secrets" = ./how-to/platform/secrets-cluster.nix;
"how-to-platform-sops" = ./how-to/platform/sops-secrets-cluster.nix;
"how-to-platform-cloudflare-tunnel" = ./how-to/platform/cloudflare-tunnel-cluster.nix;
};
};

View source on GitHub ↗

Each value under clusters is a cluster function. Its attribute name becomes the CLI cluster name, while the file’s kix.buildCluster.name becomes the cluster identity recorded in manifests and activations.

For a single project, a compact registration is enough:

flake.nix
outputs = inputs: inputs.kixpkgs.lib.mkFlake {
inherit inputs;
clusters.application = ./cluster.nix;
};

clusterModules lists modules every cluster in the flake starts from, ahead of the cluster’s own. Use it for a setting the repository wants everywhere, such as making scorecard findings fail the build:

flake.nix
outputs = inputs: inputs.kixpkgs.lib.mkFlake {
inherit inputs;
clusters.production = ./clusters/production.nix;
clusterModules = [ { scorecard.maxSeverity = "error"; } ];
};

A cluster that needs a different value sets the option itself with lib.mkForce.

Create or update flake.lock after adding the inputs:

Run in infrastructure/
❱ nix flake lock

Commit flake.nix and flake.lock together. Other machines and CI will then evaluate the same Kix and nixpkgs revisions.

List the clusters exposed by the flake:

Run in kix-examples/
❱ kix list clusters
 NAME                              
 02-hello-world                    
 06-service-dep                    
 08-namespace-deps                 
 09-typed-options                  
 10-reuse-packages                 
 19-scorecards                     
 how-to-adoption                   
 how-to-adoption-takeover          
 how-to-application                
 how-to-auto-instantiation         
 how-to-composition                
 how-to-fragments                  
 how-to-helm-bridge                
 how-to-multi-env                  
 how-to-package-cilium             
 how-to-package-monitoring         
 how-to-package-python             
 how-to-package-stackgres          
 how-to-package-storage            
 how-to-package-valkey             
 how-to-package-velero             
 how-to-package-victoria-metrics   
 how-to-platform-cloudflare-tunnel 
 how-to-platform-gateway           
 how-to-platform-hostpath          
 how-to-platform-ingress           
 how-to-platform-monitoring        
 how-to-platform-network-policy    
 how-to-platform-secrets           
 how-to-platform-sops              
 how-to-stateful-migration

If the flake is not in the current directory, pass it explicitly:

❱ kix list clusters --flake ./infrastructure

You can now use the discovered names with check, build, diff, deploy, and the other cluster commands.