No description
  • Rust 81.4%
  • Nix 17.2%
  • Python 1.3%
  • Shell 0.1%
Find a file
Raito Bezarius c3a98201ac nix/host/custom: store the job handle
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2026-01-18 15:16:49 +00:00
arcana nix/host/custom: store the job handle 2026-01-18 15:16:49 +00:00
arcana-base-server chore: release 0.6.0 2025-10-21 09:26:48 +02:00
arcana-nixos-server chore: release 0.6.0 2025-10-21 09:26:48 +02:00
arcana-proto/activation style: rename colmena-proto to arcana-proto 2025-10-20 22:32:58 +02:00
integration-tests feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
manual feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
nix feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
.editorconfig .editorconfig: Enforce .json indentation 2024-11-07 16:24:44 -07:00
.envrc feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
.gitattributes .gitattribute: Don't count the vendored highlight.js in language stats 2021-11-18 01:10:44 -08:00
.gitignore feat(custom-nixos-server): custom activation server for NixOS 2025-10-16 22:11:12 +02:00
.srcignore docs: update all docs to match new renaming 2025-10-21 08:18:24 +02:00
Cargo.lock chore: release 0.6.0 2025-10-21 09:26:48 +02:00
Cargo.toml style: rename colmena to arcana 2025-10-20 22:32:58 +02:00
default.nix feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
flake.lock feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
flake.nix feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00
LICENSE LICENSE: Update year to 2022 2022-01-03 10:37:03 -08:00
README.md docs: update all docs to match new renaming 2025-10-21 08:18:24 +02:00
renovate.json renovate.json: Group non-major updates together 2024-11-07 16:24:44 -07:00
shell.nix feat: Make flakeless a first-tier citizen 2025-12-21 22:41:53 +01:00

Arcana

Arcana is a simple, stateless NixOS deployment tool modeled after NixOps and morph, written in Rust. It's a fork of the original colmena with added features. It's a thin wrapper over Nix commands like nix-instantiate and nix-copy-closure, and supports parallel deployment.

Now with 100% more flakes! See Tutorial with Flakes below.

$ arcana apply --on @tag-a
[INFO ] Enumerating systems...
[INFO ] Enumerating nodes...
[INFO ] Selected 7 out of 45 hosts.
  (...) ✅ 0s Build successful
  sigma 🕗 7s copying path '/nix/store/h6qpk8rwm3dh3zsl1wlj1jharzf8aw9f-unit-haigha-agent.service' to 'ssh://root@sigma.redacted'...
  theta ✅ 7s Activation successful
  gamma 🕘 8s Starting...
  alpha ✅ 1s Activation successful
epsilon 🕗 7s copying path '/nix/store/fhh4rfixny8b21l6jqzk7nqwxva5k20h-nixos-system-epsilon-20.09pre-git' to 'ssh://root@epsilon.redacted'...
   beta 🕗 7s removing obsolete file /boot/kernels/z28ayg10kpnlrz0s2qrb9pzv82lc20s2-initrd-linux-5.4.89-initrd
  kappa ✅ 2s Activation successful

Installation

arcana is not included in Nixpkgs for now.

To run arcana, you need to clone this repo and build it:

nix build .#defaultPackage.x86_64-linux

Tutorial

See Tutorial with Flakes for usage with Nix Flakes.

Arcana should work with your existing colmena configurations with minimal modification. Here is a sample hive.nix with two nodes, with some common configurations applied to both nodes:

{
  meta = {
    # Override to pin the Nixpkgs version (recommended). This option
    # accepts one of the following:
    # - A path to a Nixpkgs checkout
    # - The Nixpkgs lambda (e.g., import <nixpkgs>)
    # - An initialized Nixpkgs attribute set
    nixpkgs = <nixpkgs>;

    # You can also override Nixpkgs by node!
    nodeNixpkgs = {
      node-b = ./another-nixos-checkout;
    };

    # If your Colmena host has nix configured to allow for remote builds
    # (for nix-daemon, your user being included in trusted-users)
    # you can set a machines file that will be passed to the underlying
    # nix-store command during derivation realization as a builders option.
    # For example, if you support multiple orginizations each with their own
    # build machine(s) you can ensure that builds only take place on your
    # local machine and/or the machines specified in this file.
    # machinesFile = ./machines.client-a;
  };

  defaults = { pkgs, ... }: {
    # This module will be imported by all hosts
    environment.systemPackages = with pkgs; [
      vim wget curl
    ];

    # By default, Colmena will replace unknown remote profile
    # (unknown means the profile isn't in the nix store on the
    # host running Colmena) during apply (with the default goal,
    # boot, and switch).
    # If you share a hive with others, or use multiple machines,
    # and are not careful to always commit/push/pull changes
    # you can accidentaly overwrite a remote profile so in those
    # scenarios you might want to change this default to false.
    # deployment.replaceUnknownProfiles = true;
  };

  host-a = { name, nodes, ... }: {
    # The name and nodes parameters are supported in Colmena,
    # allowing you to reference configurations in other nodes.
    networking.hostName = name;
    time.timeZone = nodes.host-b.config.time.timeZone;

    boot.loader.grub.device = "/dev/sda";
    fileSystems."/" = {
      device = "/dev/sda1";
      fsType = "ext4";
    };
  };

  host-b = {
    # Like NixOps and morph, Colmena will attempt to connect to
    # the remote host using the attribute name by default. You
    # can override it like:
    deployment.targetHost = "host-b.mydomain.tld";

    # It's also possible to override the target SSH port.
    # For further customization, use the SSH_CONFIG_FILE
    # environment variable to specify a ssh_config file.
    deployment.targetPort = 1234;

    # Override the default for this target host
    deployment.replaceUnknownProfiles = false;

    # You can filter hosts by tags with --on @tag-a,@tag-b.
    # In this example, you can deploy to hosts with the "web" tag using:
    #    arcana apply --on @web
    # You can use globs in tag matching as well:
    #    arcana apply --on '@infra-*'
    deployment.tags = [ "web" "infra-lax" ];

    time.timeZone = "America/Los_Angeles";

    boot.loader.grub.device = "/dev/sda";
    fileSystems."/" = {
      device = "/dev/sda1";
      fsType = "ext4";
    };
  };
}

Run arcana build in the same directory to build the configuration, or do arcana apply to build and deploy it to all nodes.

Tutorial with Flakes

To use with Nix Flakes, create outputs.arcana in your flake.nix.

Here is a short example:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  };
  outputs = { nixpkgs, ... }: {
    arcana = {
      meta = {
        nixpkgs = import nixpkgs {
          system = "x86_64-linux";
        };
      };

      # Also see the non-Flakes hive.nix example above.
      host-a = { name, nodes, pkgs, ... }: {
        boot.isContainer = true;
        time.timeZone = nodes.host-b.config.time.timeZone;
      };
      host-b = {
        deployment = {
          targetHost = "somehost.tld";
          targetPort = 1234;
          targetUser = "luser";
        };
        boot.isContainer = true;
        time.timeZone = "America/Los_Angeles";
      };
    };
  };
}

Run arcana build in the same directory to build the configuration, or do arcana apply to build and deploy it to all nodes.

Manual

Work in progress.

Environment Variables

  • SSH_CONFIG_FILE: Path to a ssh_config file

Current Limitations

  • It's required to use SSH keys to log into the remote hosts, and interactive authentication will not work.
  • Error reporting is lacking.

Licensing

Arcana is available under the MIT License.