Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

Flake.nix setup

To get started you’ll need a flake.nix file that looks something like this:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nix-caliga = {
      url = "github:nix-caliga/nix-caliga";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs: {
    caligaConfigurations.x86_64-linux = {
      myimage = inputs.nix-caliga.lib.makeCaligaConfigurations {
        pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
        modules = [ ./images/myimage ];
      };
    };
  };
}

Edit the name myimage as you like, and the path ./images/myimage to match the path the image configuration you make below.

Image hash

First, pickout which base image you want to use. See Setting Base Image OS for a list of base images currently in testing.
Then you’ll want to prefetch the bootc image hash. You can use nix-prefetch-docker for this:

nix run nixpkgs#nix-prefetch-docker -- --image-name quay.io/fedora/fedora-bootc --image-tag 44

Output will look something like:

{
  imageName = "quay.io/fedora/fedora-bootc";
  imageDigest = "sha256:a7f0ccdc982acf78351fc3f425729d1f45e2779b69201350ebff207730ab3a29";
  hash = "sha256-cJO4HhJkY+6kUu757PUBdQabjGLxollJV2W1iyq2TBY=";
  finalImageName = "quay.io/fedora/fedora-bootc";
  finalImageTag = "44";
}

Image Configuration

A full file example is at the end, you can also look at the project’s examples/ folder.
Start by filling in the image information from nix-prefetch-docker.

{ pkgs, ... }:

{
  config = {
    layeredImage = {
      # This is the name of the resulting image you make
      name = "ghcr.io/nix-caliga/nix-caliga";
      # This is the tag of the resulting image you make
      tag = "tag";
      fromImage = pkgs.dockerTools.pullImage {
        # These come from nix-prefetch-docker
        imageName = "quay.io/fedora/fedora-bootc";
        imageDigest = "sha256:a7f0ccdc982acf78351fc3f425729d1f45e2779b69201350ebff207730ab3a29";
        hash = "sha256-cJO4HhJkY+6kUu757PUBdQabjGLxollJV2W1iyq2TBY=";
        finalImageTag = "44";
      };
    };
  };
}

Nix-caliga makes no changes by default, so you need to select what modules you need.
I recommend starting with config.caliga.core.enable = true to enable all core modules, as well as setting config.caliga.os to your base image’s OS.
I also recommend setting the current NixOS version for the state version.

{ pkgs, ... }:
{
  config = {
    
    ...
    # set your base image OS
    caliga.os = "fedora";
    # this enables all core modules for nix-caliga
    caliga.core.enable = true;
    # set the current nixos version
    system.stateVersion = "25.11";
  };
}

Now you can start adding configuration, such as a user account, and maybe some nixpkgs you want available.
To configure systemd service, take a look here. They are configured the same as systemd on NixOS.

{ pkgs, ... }:

{
  config = {
    
    ...
    # set your username
    users.users.yourUser = {
      isNormalUser = true;
      uid = 1001;
      description = "Example User";
      # This will set your password at first login, it can be changed afterward
      initialPassword = "password";
    };

    # a list of nixpkgs you want available to all users
    environment.systemPackages = [ 
      pkgs.cowsay
      pkgs.nixfmt
    ];
  };
}

Full Example Image Config

{ pkgs, ... }:

{
  config = {
    layeredImage = {
      # This is the name of the resulting image you make
      name = "ghcr.io/nix-caliga/nix-caliga";
      # This is the tag of the resulting image you make
      tag = "tag";
      fromImage = pkgs.dockerTools.pullImage {
        # These come from nix-prefetch-docker
        imageName = "quay.io/fedora/fedora-bootc";
        imageDigest = "sha256:a7f0ccdc982acf78351fc3f425729d1f45e2779b69201350ebff207730ab3a29";
        hash = "sha256-cJO4HhJkY+6kUu757PUBdQabjGLxollJV2W1iyq2TBY=";
        finalImageTag = "44";
      };
    };

    # set your base image OS
    caliga.os = "fedora";
    # this enables all core modules for nix-caliga
    caliga.core.enable = true;
    # set the current nixos version
    system.stateVersion = "25.11";

    # set your username
    users.users.yourUser = {
      isNormalUser = true;
      uid = 1001;
      description = "Example User";
      # This will set your password at first login, it can be changed afterward
      initialPassword = "password";
    };

    # a list of nixpkgs you want available to all users
    environment.systemPackages = [
      pkgs.cowsay
      pkgs.nixfmt
    ];
  };
}

Building the Image

Build and load the resulting image:

nix build .#caligaConfigurations.x86_64-linux.myimage.config.build.image && ./result | podman load

Using the Image

You can test the image as a container with podman, replace the image name with your newly created image.

podman run -it --rm ghcr.io/nix-caliga/nix-caliga:tag

To install the image to a disk or VM, use bootc-image-builder which can make a bunch of different disk image formats from your bootc image.
For more information on working with bootc images, see the bootc documentation.