Home Installing Flakes into a NixOS 22.11 System
Post
Cancel

Installing Flakes into a NixOS 22.11 System

I’ve been experimenting with NixOS a lot recently and came across a Nix Flake I wanted to install as it contained a service I wanted to setup. The official wiki does not contain a working example for NixOS 22.11 - so here is an article that does! Come join me after the jump.


I haven’t talked about NixOS much on this site yet, however I have a set of tutorials on the way. As of the time of the original posting, the current version is 22.11. When searching the internet I found many tutorials on how to install a Nix Flake and most that I found completely failed. I presume that this is due to updated syntax regarding flakes, as this is still currently an experimental feature.

A Nix Flake is essentially a different method of creating a Nix package. It provides a different interface allowing for the use of packages and files that are not within the Nix package manager such as git repositories. It was designed to assist with development environments.

In this case I wanted to install Foundry VTT using the flake created by reckenrode on github nix-foundryvtt. The choice of flake is not important for this tutorial - however I think it’s best to have a working example. I will write a separate article on properly setting this up at a later date.

Creating flake.nix for the System

The first point of note is that nix-rebuild will automatically read a configuration from /etc/nixos/flake.nix if it detects one instead of the default /etc/nixos/configuration.nix. The flake file here is where the magic happens as we turn the system configuration itself into a flake. The following is an example of what you can put in your flake.nix file:

1
2
3
4
5
6
7
8
9
10
11
12
{
  inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-22.11;
  inputs.foundryvtt.url = github:MatteoJoliveau/nix-foundryvtt/ae6bf85b619558c4d1a828de03fd2a88313db1db;

  outputs = { self, nixpkgs, ... }@inputs: {
    nixosConfigurations.myhostname = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [ ./configuration.nix ];
    };
  };
}

A flake has both inputs and outputs. The inputs are what other things this flake requires. In this example, the nixos packages repository and the nix-foundryvtt repository is specified as the inputs.

There are many different ways to specify URLs. You can find a full list in the flake manual. While it seems like we have two styles here, both use the github type that allows one to neatly specify a project on github as well as a revision or tag. The official format for this is as follows:

1
github:<owner>/<repo>(/<rev-or-ref>)?(\?<params>)?

This allows you to specify owner/repo simply and it will pull directly via git https. After this, you can specify a specific revision/commit/tag from the repository. We have two examples from here:

  • github:NixOS/nixpkgs/nixos-22.11; - This specifies the github url for accessing nix packages. NixOS is the owner, nixpkgs is the repository and nixos-22.11 is the git tag.
  • github:MatteoJoliveau/nix-foundryvtt/ae6bf85b619558c4d1a828de03fd2a88313db1db; This specifies a specific commit hash to use and as such will not update unless you change it manually. (NOTE: this revision is actually from a PR to the main foundry repository).

UPDATE - The PR has now been merged. Look at my post on setting up FoundryVTT here for the updated details.

The outputs also has a few variables it pulls from the outer scope { self, nixpkgs, ... } as well as @inputs that pulls in all the members of inputs into the scope.

The next line (nixosConfigurations.myhostname = nixpkgs.lib.nixosSystem {) specifies that we’re creating a system configuration. nix-rebuild will automatically choose the configuration that has the same hostname as the current host by default (you can manually choose if you wish). The system line will have to be modified depending on CPU architecture, and the modules line specifies which configuration files to include from here.

The final bit of magic is the specialArgs = { inherit inputs; }; line. This allows the specified modules to inherit all of the member variables from inputs, allowing you to import the modules into your main configuration.nix and any further modules within it.

Now the hard part is out of the way, lets have a look at what to put into your configuration.

Importing the Flake into configuration.nix

In order to use the modules you’ve imported from your flakes, you have to add them to your imports in configuration.nix. The following example is actually from a separate module aptly named foundry.nix that is imported into the primary file.

1
2
3
4
5
6
7
8
9
10
{ inputs, ... }:
{
	imports = [ inputs.foundryvtt.nixosModules.foundryvtt ];
	services.foundryvtt = {
		enable = true;
		hostname = "myhostname.com";
		proxySSL = true;
		proxyPort = 443;
	};
}

The key line is imports = [ inputs.foundryvtt.nixosModules.foundryvtt ];. This will import the module from the flake into the current nix file allowing you to use it as you wish. In this case a service called foundryvtt has been predefined and is enabled here along with a few other settings. The settings for this particular module will be explained in a later tutorial.

Some Final Thoughts

Nix Flakes allows for an easy way to set up an environment that contains a mixture of nix packages and other files or repositories. This is a very powerful system, as it also is possible to make a NixOS configuration out of one. I hope that someday its feature-set and configuration will be stabilised and official tutorials/wiki can be kept up-to-date. It is an experimental feature, and as such I understand that things can change quickly. I appreciate all the good work going into making such a feature as I think it’s a great extension to the declarative nature of NixOS and the nix packaging system.

If you found this useful, then share this around to those that may find it useful! Please leave a comment down below if you have any questions or something else to say!