Skip to content

First Steps with CTRL-OS

This section explains common first steps to use CTRL-OS in your project.

Using CTRL-OS

To use CTRL-OS, your project needs to build using its source tarball instead of Nixpkgs.

The way this is done depends on the way your project is structured. For a NixOS system, the common ways are using the nix-channel semantics, or Flakes. For any other project depending on Nixpkgs, the pinned reference to Nixpkgs will need to be updated, whether it's through Flakes, npins, Nix, or other schemes.

Using CTRL-OS with a NixOS system

As a Flake input

The CTRL-OS release tarball can be used as a Flake input.

Update the nixpkgs input URL to point to the CTRL-OS release tarball.

Note

The following example used a freshly generated NixOS configuration as the first step, edited to point to 24.05 as an example.

There is no need to generate a configuration when starting from your existing configuration.

$ nixos-generate-config --flake
[...]

$ git diff --unified=1
diff --git i/flake.nix w/flake.nix
index 62f5495..6334105 100644
--- i/flake.nix
+++ w/flake.nix
@@ -3,3 +3,3 @@
     # Use `nix flake update` to update the flake to the latest revision of the chosen release channel.
-    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
+    nixpkgs.url = "https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz";
   };

$ nix flake update
warning: Git tree '...' is dirty
warning: updating lock file '.../flake.lock':
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/0000000000000000000000000000000000000000' (2024-12-30)
  → 'https://channels.ctrl-os.com/permanent/ctrlos-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.tar.xz?narHash=sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D' (20XX-MM-DD)
warning: Git tree '...' is dirty

Afterward, building the system as a Flake will refer to the pinned CTRL-OS.

As a system-wide channel

If your system uses the legacy nix-channel semantics, you will need to change the system-wide nixos channel reference to refer to the CTRL-OS tarball.

This follows the same procedure as upgrading between NixOS releases. The channel name should still be nixos (the last parameter) as this is the identifier used to refer to the Nixpkgs input when building NixOS with nix-channel semantics.

$ sudo nix-channel --list
nixos https://channels.nixos.org/nixos-24.05

$ sudo nix-channel --add https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz nixos

$ sudo nix-channel --list
nixos https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz

$ sudo nix-channel --update
this derivation will be built:
  /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-nixos-24.05.tar.xz.drv
building '/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-nixos-24.05.tar.xz.drv'...
unpacking 1 channels...

Note

When using the legacy nix-channel semantics, a NixOS system evaluates using the system-wide channels, which are owned and manage by the root user.

If your user has a nixos channel configured, you may want to remove it to prevent unexpected results.

Using CTRL-OS for other projects

Projects that are not building an operating system can also benefit from CTRL-OS. The release cadence of NixOS makes it hard to keep using stable-versioned dependencies, while keeping-up with security issues.

CTRL-OS can be used in your Nix-built project, regardless of the way inputs are referenced.

As a Flake Input

Similarly to the system configuration, the release tarball can be used in any Flake. Typically, the nixpkgs input would be set to the CTRL-OS release tarball.

# flake.nix
{
  description = "A Very Basic CTRL-OS Flake";

  inputs = {
    # Use the CTRL-OS release tarball as nixpkgs input.
    nixpkgs.url = "https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz";
  };

  outputs = { self, nixpkgs }: {
    packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;
    packages.x86_64-linux.default = self.packages.x86_64-linux.hello;
  };
}
$ nix build '.#hello'
warning: creating lock file '.../flake.lock':
• Added input 'nixpkgs':
    'https://channels.ctrl-os.com/permanent/ctrlos-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.tar.xz?narHash=sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D' (20XX-MM-DD)

$ readlink result
/nix/store/441agxbmdlhy3ldycc98dbl5id6fqv3j-hello-2.12.1

$ ./result/bin/hello 
Hello, world!

As an npins pin

A sample project was initialized with npins init, and the following default.nix.

# default.nix
let
  sources = import ./npins;
  pkgs = import sources.nixpkgs {};
in
{
  inherit (pkgs)
    hello
  ;
}

Then npins add can be used to change the nixpkgs input URL.

$ npins add tarball --name nixpkgs https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz
[INFO ] Adding 'nixpkgs' …
    url: https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz
    hash: 0000000000000000000000000000000000000000000000000000
    frozen: false

$ git diff --unified=1
diff --git i/npins/sources.json w/npins/sources.json
index be53124..e407fd4 100644
--- i/npins/sources.json
+++ w/npins/sources.json
@@ -3,6 +3,5 @@
     "nixpkgs": {
-      "type": "Channel",
-      "name": "nixpkgs-unstable",
-      "url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre000000.eeeeeeeeeeee/nixexprs.tar.xz",
-      "hash": "0000000000000000000000000000000000000000000000000000"
+      "type": "Tarball",
+      "url": "https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz",
+      "hash": "0000000000000000000000000000000000000000000000000000"
     }

$ nix-build --attr hello
/nix/store/441agxbmdlhy3ldycc98dbl5id6fqv3j-hello-2.12.1

Other input pinning tools

The approach is the same as with the previous examples: replace your pinned URL for the Nixpkgs 24.05 release tarball with the CTRL-OS 24.05 release tarball.

-  https://channels.nixos.org/nixos-24.05/nixexprs.tar.xz
+  https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz

Don't forget to re-lock the dependencies, which will depend on the exact tool used!

As a user-configured channel

Warning

Outside of a system build, it is discouraged to rely on nix-channel for build inputs.

Using nix-channel semantics for non-system builds loses any tracking for the declared (or pinned) input for a given project.

Follow the instructions under As a system-wide channel. You may change the name of the input, as needed, and use nix-channel as your user instead of as root.

CTRL-OS Channels

The following channels are available for CTRL-OS:

Version Status End of Life
ctrlos-24.05 Preview May 2029

Binary Cache

Cyberus Technology maintains a binary cache, which contains pre-built software for each CTRL-OS version. We recommend using the binary cache if you use CTRL-OS, because you won't have to recompile software that our internal CI has already built.

Configuring the Binary Cache

To configure the binary cache, add it as one of the substituters and add the corresponding public key.

extra-substituters = https://cache.ctrl-os.com/
extra-trusted-public-keys = ctrl-os:baPzGxj33zp/P+GAIJXsr8ss9Law+qEEFViX1+flbv8=