This is actually a toy project for me to learn Rust. I also wanted a deployment tool not owned by anybody else.
{
inputs = {
pullix.url = "github:scarisey/pullix";
};
}Add the nixos module in the imports, for example:
{...}:{
imports = [
./hardware.nix
inputs.pullix.nixosModules.default
];
}Then configure the service:
{...}:{
services.pullix = {
enable = true;
hostname = "foo";
pollIntervalSecs = 10;
flakeRepo = {
type = "GitHub";
repo = "scarisey/nixos-dotfiles";
prodSpec = {
ref = "prod";
};
testSpec = {
ref = "test";
};
};
environmentFile = config.sops.secrets."nix_config_env".path;
verbose_logs = true;
};
}Pullix is a pull-based deployment daemon that periodically polls a remote Git repository and deploys NixOS configurations automatically. Here is how it works:
- Polling: At a configurable interval, Pullix fetches all refs from the remote repository.
- Commit resolution: It resolves two configured refs — a test ref and a prod ref (branches or tags) — to their latest commit SHAs, and computes the distance (number of commits) between them.
- Deployment decision: Based on the commit distance and deployment history:
- If test is ahead of prod, the test commit is deployed (if not already seen).
- If prod is ahead of or equal to test, the prod commit is deployed (if not already seen).
- If only one ref exists, that ref is deployed.
- Previously failed commits are not retried unless a new commit appears on that ref.
- NixOS activation:
- Test deployments run
nix buildthenswitch-to-configuration test— the configuration is activated but not added as the boot default. - Prod deployments run
nix buildthenswitch-to-configuration switch— the configuration is activated and set as the boot default.
- Test deployments run
- State persistence: Deployment history (successes and failures) is saved to a local JSON file, ensuring Pullix never redeploys an already-processed commit across restarts.
- Type:
bool - Default:
false - Description: Whether to enable the Pullix deployment service.
- Type: attribute set (submodule)
- Description: Flake reference configuration for the repository to deploy from.
- Type: one of
"Git","GitHttp","GitHttps","GitSsh","GitFile","GitHub","GitLab","SourceHut","Mercurial","Tarball","File","Path","Indirect" - Required
- Description: Type of flake reference.
- Type:
str - Required
- Description: Repository URL or identifier (e.g.
"owner/repo"for GitHub/GitLab/SourceHut, or a full URL for Git types).
- Type:
nullorstr - Default:
null - Description: Custom host for self-hosted git servers (e.g. a self-hosted GitLab instance).
- Type:
nullor attribute set (submodule) - Default:
null - Description: Config for prod deployment (
switch-to-configuration switch). When the prod ref is ahead of or equal to the test ref, Pullix activates the configuration and sets it as the boot default.
- Type:
nullorstr - Default:
null - Description: Git reference (branch name) to track for prod.
- Type:
nullorstr - Default:
null - Description: Git revision (commit SHA or tag) to pin for prod.
- Type:
nullor attribute set (submodule) - Default:
null - Description: Config for test deployment (
switch-to-configuration test). When the test ref is ahead of prod, Pullix activates the configuration without making it the boot default.
- Type:
nullorstr - Default:
null - Description: Git reference (branch name) to track for test.
- Type:
nullorstr - Default:
null - Description: Git revision (commit SHA or tag) to pin for test.
- Type:
int - Default:
60 - Description: Polling interval in seconds. Pullix will fetch the remote repository and evaluate whether a deployment is needed at this interval.
- Type:
str - Default:
"/var/lib/pullix" - Description: Directory for Pullix state files. A
state.jsonfile tracking deployment history is stored here. The directory is automatically created viasystemd.tmpfiles.
- Type:
str - Default:
config.networking.hostName - Description: Hostname used for the
nixosConfigurations.<hostname>lookup in the flake. This determines which NixOS configuration from the flake is built and deployed.
-
Type:
nullorpath -
Default:
null -
Description: Path to an additional environment file to source for the Pullix systemd service. Useful for passing secrets such as Nix access tokens without storing them in the Nix store. Example content:
NIX_CONFIG=access-tokens = github.com=ghp_xxx
- Type:
nullorstr - Default:
null - Description: Endpoint for OpenTelemetry HTTP exporter.
- Type:
nullor attribute set (submodule) - Default:
null - Description: SSH private key configuration for accessing private Git repositories over SSH.
- Type:
path - Required
- Description: Path to the SSH private key file.
- Type:
path - Required
- Description: Path to a file containing the passphrase for the private key.
- Type:
bool - Default:
false - Description: When enabled, sets
RUST_LOG=DEBUGin the service environment, making logs very verbose. Useful for troubleshooting deployment issues.