Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 179 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,125 +15,227 @@

</div>

This project provides a basic method to manage system configuration using [Nix][nixos]
on any Linux distribution.
It builds on the many modules that already exist in [NixOS][nixos].
System manager is a tool to configure Linux machines. Unlike Chef, Puppet and Ansible, it only controls a small subset, and most of its changes are done in an immutable layer, thanks to the power of Nix.

*Warning*: System Manager is a work in progress, you can expect things not to work or to break.
Using NixOS-style declarative configurations, you describe what your system should look like, by specifying packages, services, and settings all in Nix, then apply it safely and atomically with a single command. Each change is reproducible, just like NixOS generations.

[nixos]: https://nixos.org
You don't need to be an expert in Nix to use it, as its syntax is straightforward. But if you're familiar with Nix and Home Manager, think of System Manager as being similar, but for your entire machine. Whereas Home Manager manages user environments, System Manager manages the entire system, starting at root-level configurations, packages, and services, using the same reliable, Nix-based model.

## Usage
System Manager builds on the many modules that already exist in [NixOS].

### Install Nix
## Quick Example to Get Started

In order to use System Manager, you will first need to install Nix.
You can either use your distro's package manager, or use one of the available options
to install Nix.
We will assume you're using a non-NixOS distribution (such as Ubuntu) and you have Nix already installed, with flakes enabled.

- [Official Nix Installer][official-installer] - The canonical source for installing nix.
- [Determinate Nix Installer][detsys-installer] - A wrapper around the official installer that has SELinux support, and enables flake features by default.
System Manager has an "init" subcommand that can build a set of starting files for you. By default, it places the files in `~/.config/system-manager`. You can run this init subcommand by typing:

> Note: Be advised that the Determinate Systems installer has the option for the official
> Nix as well as Determinate's own variant of Nix (Determinate Nix). It will prompt you
> for which one you want to install. System Manager is not tested against Determinate Nix.
> It's recommended to use the official Nix if installing via the Determinate Nix Installer.
```
nix run 'github:numtide/system-manager' -- init
```

[official-installer]: https://nixos.org/download.html
[detsys-installer]: https://github.com/DeterminateSystems/nix-installer
If you see an error regarding experimental nix features, instead type the following:

```
nix run 'github:numtide/system-manager' --extra-experimental-features 'nix-command flakes' -- init
```

> [!Tip]
> If you still have problems running this step, check out our full Getting Started guide, which includes how to handle issues of running as root, and whether you've installed Nix to be used by a single user.
## Usage with flakes
> [!Note]
> You can optionally run the above under `sudo`, which will place the files under `/root/.config/system-manager`. You might need to pass the path, depending on how you installed Nix:
> `sudo env PATH="$PATH" nix run 'github:numtide/system-manager' -- init`
### Defining the configuration
You will now have two files under `~/.config/system-manager` (or `/root/.config/system-manager` if you ran the above under sudo):

A basic Nix flake using System Manager would look something like this:
- flake.nix
- system.nix

Go ahead and switch to the folder:

```
cd ~/.config/system-manager
```

(Or to the root equivalent.)

Here is what flake.nix looks like:

```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
description = "Standalone System Manager configuration";
inputs = {
# Specify the source of System Manager and Nixpkgs.
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
system-manager = {
url = "github:numtide/system-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, flake-utils, nixpkgs, system-manager }: {
systemConfigs.default = system-manager.lib.makeSystemConfig {
modules = [
./modules
];
outputs =
{
self,
nixpkgs,
system-manager,
...
}:
{
systemConfigs.default = system-manager.lib.makeSystemConfig {
# Specify your system configuration modules here, for example,
# the path to your system.nix.
modules = [ ./system.nix ];
# Optionally specify extraSpecialArgs and overlays
};
};
};
}
```

And you would then put your System Manager modules in the `modules` directory,
which should contain a `default.nix` file which functions as the entrance point.
For these examples, we won't use the `system.nix` file; we'll create separate configuration files for each example.

A simple System Manager module could look something like this:
Find the following line in `flake.nix`:

```nix
{ config, lib, pkgs, ... }:
```
modules = [ ./system.nix ];
```

and change it to this:

```
modules = [ ./cli_tools.nix ];
```

Create a file in the same folder called `cli_tools.nix` and add the following into it:

```nix
{ pkgs, ... }:
{
config = {
nixpkgs.hostPlatform = "x86_64-linux";
environment.systemPackages = with pkgs; [
btop # Beautiful system monitor
bat # Modern 'cat' with syntax highlighting
];
};
}
environment = {
etc = {
"foo.conf".text = ''
launch_the_rockets = true
'';
};
systemPackages = [
pkgs.ripgrep
pkgs.fd
pkgs.hello
];
```

This specifies a configuration that includes `btop` and `bat` to be installed on the system. To do so, execute System Manager with `sudo` using the nix command (assuming you have experimental features nix-command and flakes turned on):

```
sudo env PATH="$PATH" nix run 'github:numtide/system-manager' -- switch --flake .
```

Notice we're passing the current `PATH` environment into `sudo` so that the elevated shell can locate the `nix` command.

Also, note that you might need to enable `nix-commands` and `flakes` if you don't already have them set:

```
sudo env PATH="$PATH" nix --extra-experimental-features 'nix-command flakes' run 'github:numtide/system-manager' -- switch --flake .
```

> [!Note]
> The first time you run System Manager, it will update your path by adding an entry in the /etc/profile.d folder. For this change to take effect, you need to log out and then log back in. However, if you don't want to log out, you can source the file:
> `source /etc/profile.d/system-manager-path.sh`
And now the two commands `btop` and `bat` should be available on your system:

```
$ btop --version
btop version: 1.4.5
Compiled with: g++ (14.3.0)
Configured with: cmake -DBTOP_STATIC=OFF -DBTOP_GPU=ON
$ bat --version
bat 0.26.0
```

Want to remove a package? Simply remove it or comment it out in the `cli_tools.nix` file, and run it again. For example, if you want to remove `bat`, simply update the `default.nix` to the following:

```nix
{ pkgs, ... }:
{
nixpkgs.hostPlatform = "x86_64-linux";
environment.systemPackages = with pkgs; [
btop # Beautiful system monitor
# bat # Comment out or remove
];
}
```

## Regarding the Error

You might notice an error that looks like this:

`[2025-11-17T15:06:46Z ERROR system_manager::activate::etc_files] Error while trying to link directory /etc/.system-manager-static/nix: Unmanaged path already exists in filesystem, please remove it and run system-manager again: /etc/nix/nix.conf`

You can safely ignore it; or, you can allow System Manager to take control of `nix.conf`. If you choose to have System Manager take control of `nix.conf`, rename `nix.conf` to a backup name, such as `nix_conf_backup`, and run System Manager again. Note, however, that if you had settings in your `nix.conf` file, they might not appear in the new file System Manager generates. For that read the following section, [Adding in Experimental Features](#adding-in-experimental-features).

## Adding in Experimental Features

It's possible that you had a `nix.conf` file in `/etc/nix` that had experimental features set. And if you allowed System Manager to take control of that file, your setting will likely be gone. But that's okay; you now have control of your system right from the `flake.nix` file. You can add experimental features inside the modules list like so:

```nix
{
description = "Standalone System Manager configuration";
inputs = {
# Specify the source of System Manager and Nixpkgs.
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
system-manager = {
url = "github:numtide/system-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
systemd.services = {
foo = {
enable = true;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
wantedBy = [ "system-manager.target" ];
script = ''
${lib.getBin pkgs.hello}/bin/hello
echo "We launched the rockets!"
'';
outputs =
{
self,
nixpkgs,
system-manager,
...
}:
{
systemConfigs.default = system-manager.lib.makeSystemConfig {
# Specify your system configuration modules here, for example,
# the path to your system.nix.
modules = [
# Place additional settings here:
{
nix.settings.experimental-features = "nix-command flakes";
}
./cli_tools.nix
];
# Optionally specify extraSpecialArgs and overlays
};
};
};
}
```

### Activating the configuration
Then re-run System Manager and your changes will take effect; now you should have the two experimental features set, `nix-command` and `flakes`.

Once the configuration is defined, you can activate it using the `system-manager` CLI:
```sh
nix run 'github:numtide/system-manager' -- switch --flake '.'
```
# Full Installation and setup

### Reproducibility
## Install Nix

By design flakes run in [pure evaluation mode](https://wiki.nixos.org/wiki/Flakes#Making_your_evaluations_pure).
In some cases you may not want this. To run an impure evaluation of the flake, add the following option to your command:
```sh
--nix-option pure-eval false
```
System manager itself does not need to be installed; but, you do need to install Nix. (However, you can optionally install system-manager locally if you prefer.)

To install Nix, you can either use your distro's package manager, or use one of the following available options to install Nix.

## Currently supported features
- [Official Nix Installer][official-installer] - The canonical source for installing nix.
- [Determinate Nix Installer][detsys-installer] - A wrapper around the official installer that has
SELinux support, and enables flake features by default.

Currently it is possible to configure files under `/etc/` and systemd services.
More features may follow later.
> [!Tip]
> Some Nix users have had difficulty installing Nix on Windows Subsystem for Linux (WSL) using the official installer. If you're using WSL, we recommend using Determinate Nix installer.
### Supported Systems
## Supported Systems

System Manager is currently only supported on NixOS and Ubuntu. However, it can be used on other distributions by enabling the following:

Expand All @@ -154,3 +256,7 @@ Looking for help or customization?

Get in touch with Numtide to get a quote. We make it easy for companies to
work with Open Source projects: <https://numtide.com/contact>

[detsys-installer]: https://github.com/DeterminateSystems/nix-installer
[nixos]: https://nixos.org
[official-installer]: https://nixos.org/download.html
1 change: 1 addition & 0 deletions documentation/.envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
1 change: 1 addition & 0 deletions documentation/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
site/
Loading