# homelab-deploy A message-based deployment system for NixOS configurations using NATS for messaging. Deploy NixOS configurations across a fleet of hosts with support for tiered access control, role-based targeting, and AI assistant integration. ## Overview The `homelab-deploy` binary provides three operational modes: 1. **Listener mode** - Runs on each NixOS host as a systemd service, subscribing to NATS subjects and executing `nixos-rebuild` when deployment requests arrive 2. **MCP mode** - Runs as an MCP (Model Context Protocol) server, exposing deployment tools for AI assistants 3. **CLI mode** - Manual deployment commands for administrators ## Installation ### Using Nix Flakes ```bash # Run directly nix run github:torjus/homelab-deploy -- --help # Add to your flake inputs { inputs.homelab-deploy.url = "github:torjus/homelab-deploy"; } ``` ### Building from source ```bash nix develop go build ./cmd/homelab-deploy ``` ## CLI Usage ### Listener Mode Run on each NixOS host to listen for deployment requests: ```bash homelab-deploy listener \ --hostname myhost \ --tier prod \ --nats-url nats://nats.example.com:4222 \ --nkey-file /run/secrets/listener.nkey \ --flake-url git+https://git.example.com/user/nixos-configs.git \ --role dns \ --timeout 600 ``` #### Listener Flags | Flag | Required | Description | |------|----------|-------------| | `--hostname` | Yes | Hostname for this listener | | `--tier` | Yes | Deployment tier (`test` or `prod`) | | `--nats-url` | Yes | NATS server URL | | `--nkey-file` | Yes | Path to NKey seed file | | `--flake-url` | Yes | Git flake URL for nixos-rebuild | | `--role` | No | Role for role-based targeting | | `--timeout` | No | Deployment timeout in seconds (default: 600) | | `--deploy-subject` | No | NATS subjects to subscribe to (repeatable) | | `--discover-subject` | No | Discovery subject (default: `deploy.discover`) | #### Subject Templates Deploy subjects support template variables that are expanded at startup: - `` - The listener's hostname - `` - The listener's tier - `` - The listener's role (subjects with `` are skipped if role is not set) Default subjects: ``` deploy.. deploy..all deploy..role. ``` ### Deploy Command Deploy to hosts via NATS: ```bash # Deploy to a specific host homelab-deploy deploy deploy.prod.myhost \ --nats-url nats://nats.example.com:4222 \ --nkey-file /run/secrets/deployer.nkey \ --branch main \ --action switch # Deploy to all test hosts homelab-deploy deploy deploy.test.all \ --nats-url nats://nats.example.com:4222 \ --nkey-file /run/secrets/deployer.nkey # Deploy to all prod DNS servers homelab-deploy deploy deploy.prod.role.dns \ --nats-url nats://nats.example.com:4222 \ --nkey-file /run/secrets/deployer.nkey ``` #### Deploy Flags | Flag | Required | Env Var | Description | |------|----------|---------|-------------| | `--nats-url` | Yes | `HOMELAB_DEPLOY_NATS_URL` | NATS server URL | | `--nkey-file` | Yes | `HOMELAB_DEPLOY_NKEY_FILE` | Path to NKey seed file | | `--branch` | No | `HOMELAB_DEPLOY_BRANCH` | Git branch or commit (default: `master`) | | `--action` | No | `HOMELAB_DEPLOY_ACTION` | nixos-rebuild action (default: `switch`) | | `--timeout` | No | `HOMELAB_DEPLOY_TIMEOUT` | Response timeout in seconds (default: 900) | #### Subject Aliases Configure aliases via environment variables to simplify common deployments: ```bash export HOMELAB_DEPLOY_ALIAS_TEST="deploy.test.all" export HOMELAB_DEPLOY_ALIAS_PROD="deploy.prod.all" export HOMELAB_DEPLOY_ALIAS_PROD_DNS="deploy.prod.role.dns" # Now use short aliases homelab-deploy deploy test --nats-url ... --nkey-file ... homelab-deploy deploy prod-dns --nats-url ... --nkey-file ... ``` Alias lookup: `HOMELAB_DEPLOY_ALIAS_` where name is uppercased and hyphens become underscores. ### MCP Server Mode Run as an MCP server for AI assistant integration: ```bash # Test-tier only access homelab-deploy mcp \ --nats-url nats://nats.example.com:4222 \ --nkey-file /run/secrets/mcp.nkey # With admin access to all tiers homelab-deploy mcp \ --nats-url nats://nats.example.com:4222 \ --nkey-file /run/secrets/mcp.nkey \ --enable-admin \ --admin-nkey-file /run/secrets/admin.nkey ``` #### MCP Tools | Tool | Description | |------|-------------| | `deploy` | Deploy to test-tier hosts only | | `deploy_admin` | Deploy to any tier (requires `--enable-admin`) | | `list_hosts` | Discover available deployment targets | #### Tool Parameters **deploy / deploy_admin:** - `hostname` - Target specific host - `all` - Deploy to all hosts (in tier) - `role` - Deploy to hosts with this role - `branch` - Git branch/commit (default: master) - `action` - switch, boot, test, dry-activate (default: switch) - `tier` - Required for deploy_admin only **list_hosts:** - `tier` - Filter by tier (optional) ## NixOS Module Add the module to your NixOS configuration: ```nix { inputs.homelab-deploy.url = "github:torjus/homelab-deploy"; outputs = { self, nixpkgs, homelab-deploy, ... }: { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { modules = [ homelab-deploy.nixosModules.default { services.homelab-deploy.listener = { enable = true; tier = "prod"; role = "dns"; natsUrl = "nats://nats.example.com:4222"; nkeyFile = "/run/secrets/homelab-deploy-nkey"; flakeUrl = "git+https://git.example.com/user/nixos-configs.git"; }; } ]; }; }; } ``` ### Module Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `enable` | bool | `false` | Enable the listener service | | `package` | package | `pkgs.homelab-deploy` | Package to use | | `hostname` | string | `config.networking.hostName` | Hostname for subject templates | | `tier` | enum | required | `"test"` or `"prod"` | | `role` | string | `null` | Role for role-based targeting | | `natsUrl` | string | required | NATS server URL | | `nkeyFile` | path | required | Path to NKey seed file | | `flakeUrl` | string | required | Git flake URL | | `timeout` | int | `600` | Deployment timeout in seconds | | `deploySubjects` | list of string | see below | Subjects to subscribe to | | `discoverSubject` | string | `"deploy.discover"` | Discovery subject | | `environment` | attrs | `{}` | Additional environment variables | Default `deploySubjects`: ```nix [ "deploy.." "deploy..all" "deploy..role." ] ``` ## Message Protocol ### Deploy Request ```json { "action": "switch", "revision": "main", "reply_to": "deploy.responses.abc123" } ``` ### Deploy Response ```json { "hostname": "myhost", "status": "completed", "error": null, "message": "Successfully switched to generation 42" } ``` **Status values:** `accepted`, `rejected`, `started`, `completed`, `failed` **Error codes:** `invalid_revision`, `invalid_action`, `already_running`, `build_failed`, `timeout` ## NATS Authentication All connections use NKey authentication. Generate keys with: ```bash nk -gen user -pubout ``` Configure appropriate publish/subscribe permissions in your NATS server for each credential type. ## License MIT