In my last post, I discussed mapping functions from the builtins
and lib
in the minimal template flake.nix
. Now, let's finish configuring NixOS as a flake.
Initializing the directory with git
I initialized the directory using git init nix-config
and loaded it into Vscode. After making necessary changes to flake.nix
, I copied extra configuration parts from my configuration.nix
. I won't modify home.nix
for now and will keep the programs declared in configuration.nix
.
Resolving git issues
I messed up something while uploading the directory to git through Vscode, so I deleted the .git directory and tried initializing it again. Not the elegant solution yeah.
I found a helpful tutorial by Tweag on understanding Git concepts here. After committing my changes and creating a repository on GitHub, I tried to apply the flake configuration without uploading the directory, but it didn't work.
Debugging flake rebuild failure
I got an error when running sudo nixos-rebuild switch --flake .#nixos
. I tried changing the input section of my flake.nix
to reference nixos-unstable
and even removed the unstable option, but still faced errors.
❯ sudo nixos-rebuild switch --flake .#nixos
warning: updating lock file '/home/stablejoy/nix-config/flake.lock':
• Updated input 'nixpkgs':
'github:nixos/nixpkgs/0cf4274b5d06325bd16dbf879a30981bc283e58a' (2023-02-19)
→ 'github:nixos/nixpkgs/bb2009ca185d97813e75736c2b8d1d8bb81bde05' (2023-04-19)
warning: Git tree '/home/stablejoy/nix-config' is dirty
error: attribute 'nixpkgs.config.allowUnfree' already defined at /nix/store/8ji8d4jrs8w8p59x39j3krq3kmay8h85-source/nixos/configuration.nix:34:7
at /nix/store/8ji8d4jrs8w8p59x39j3krq3kmay8h85-source/nixos/configuration.nix:137:3:
136| # Allow unfree packages
137| nixpkgs.config.allowUnfree = true;
| ^
138|
(use '--show-trace' to show detailed location information)
OK, so I removed the double entry and tried again the flake build command and.. it works! But something looks odd. Why is it downloading so much? I thought a flake kind of transforms the system into a flake. What is happening? I guess since I haven't updated my NixOS system in more than couple days already it is downloading the new versions of dependencies and packages.
After 14 minutes I get this output:
nix-config on master
❯ sudo nixos-rebuild switch --flake .#nixos
[sudo] password for stablejoy:
building the system configuration...
...
activating the configuration...
setting up /etc...
restarting systemd...
...
the following new units were started: NetworkManager-dispatcher.service, run-credentials-systemd\x2dvconsole\x2dsetup.service.mount, systemd-hostnamed.service, systemd-vconsole-setup.service
nix-config on master took 14m46s
Is this it? I copy paste the output to GPT4 wishing for someone to just say yes, you did it. You got yourself a flake.
Congratulations! It seems like your NixOS rebuild has succeeded this time. The output you provided shows that the system configuration was built, and various services were stopped, changed, restarted, or started as needed. Now that you have successfully applied the flake configuration, you can continue to make changes to your NixOS setup and rebuild as necessary.
So how do we now update the system? I don't think I can use the sudo nixos-rebulid switch
command anymore.
What's next now that we have a flake?
So the flake.lock
is a generated file that records the exact versions of the flake inputs, like nixpkgs. When we update our flake enabled NixOS we will use nix flake update
which will update the flake.lock
to the latest available versions of the flake inputs. So the process goes like:
nix flake update
sudo nixos-rebuild switch --flake .#hostname
Also, the #hostname
should be changed to one's own hostname
(as declared in configuration.nix
) in case this looks confusing. Yes, Nix is declarative and functional so when I first saw this #hostname
I was thinking this is could be like bultins.currentSystem
which gets the current system version so maybe I don't have to write my own hostname, maybe the #hostname
picks up the system hostname. But this isn't the case apparently.
Let's add the Neovim flake
I'd like to add this Neovim flake now to my flake-enabled NixOS. We can run the flake with nix run github:jordanisaacs/neovim-flake
but it won't stay in the system so how do we do we add it permanently? We need to add the neovim flake to our inputs
section in the flake.nix
as it says in the TODO:
part of the minimal flake.nix
. Let's do that! Our inputs
attribute set looks like this now:
inputs = {
# Nixpkgs
nixpkgs.url = "github:nixos/nixpkgs"; # Use unstable channel instead of release
# Home manager
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
# TODO: Add any other flake you might need
# hardware.url = "github:nixos/nixos-hardware";
# Shameless plug: looking for a way to nixify your themes and make
# everything match nicely? Try nix-colors!
# nix-colors.url = "github:misterio77/nix-colors";
};
Let's add the neovim flake under the hardware.url
set:
# TODO: Add any other flake you might need
# hardware.url = "github:nixos/nixos-hardware";
neovim-flake = {
url = "github:jordanisaacs/neovim-flake";
inputs.nixpkgs.follows = "nixpkgs";
}
Now I asked GPT what does the inputs.nixpkgs.follows = "nixpkgs";
mean in this context?
When you specify follows = "nixpkgs";, you tell the neovim-flake to use the same nixpkgs input as the one defined in your flake, rather than fetching its own version of nixpkgs. This can prevent potential issues that may arise if the neovim-flake were to use a different version of nixpkgs that is not compatible with the packages in your main flake.
OK, that makes sense. I add the set and then write the file in Vscode. Vscode is then showing 1 pending changes
, then with the +
sign in Vscode we stage the changes, and then commit the changes with a commit message: adding the neovim flake into flake.nix so that it can be used as a flake input
and accept commit changes
with that little check mark on the right, then sync changes with the big green button.
OK, let's try to update our flake and see if this will be enough to have neovim flake on our system:
nix-config on master
❯ sudo nixos-rebuild switch --flake .#nixos
building the system configuration...
stopping the following units: accounts-daemon.service
NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2duuid-7A19\x2d66BE.service
activating the configuration...
setting up /etc...
reloading user units for stablejoy...
setting up tmpfiles
reloading the following units: dbus.service
restarting the following units: polkit.service
starting the following units: accounts-daemon.service
Great! It looks like it worked. If I try to run neovim
or nvim
will it work?
nix-config on master took 33s
❯ nvim
The program 'nvim' is not in your PATH. It is provided by several packages.
You can make it available in an ephemeral shell by typing one of the following:
nix-shell -p neovim
nix-shell -p neovim-unwrapped
nix-shell -p vimPlugins.vim-elixir
Nope! Oh! I didn't add the neovim-flake to my outputs section of the flake.nix
. But after adding it I get an error:
error: syntax error, unexpected ELLIPSIS, expecting '}'
at /nix/store/1wri85b2fy8f0512pd4gg4dqx3mgjddb-source/flake.nix:25:51:
24|
25| outputs = { nixpkgs, home-manager, neovim-flake ... }@inputs: {
| ^
26| # NixOS configuration entrypoint
I forgot to add the comma ,
after the neovim-flake but it would be nice if the error message explained that.
Let's try again:
nix-config on master took 2s
❯ sudo nixos-rebuild switch --flake .#nixos
building the system configuration...
activating the configuration...
setting up /etc...
reloading user units for stablejoy...
setting up tmpfiles
nix-config on master took 19s
❯ nvim
The program 'nvim' is not in your PATH. It is provided by several packages.
...
Nope! So I ask GPT what's the problem and paste in the code and we get an answer:
In your
flake.nix
file, locate the part where you define your system configuration, and addneovim-flake.defaultPackage.${system}
to the list of system packages.
Now why do we need to do that? Why do I need to edit two files instead of simply declaring the neovim-flake into the inputs
. If we look at the outputs
in the flake.nix
we can see that the outputs picks up the configuration.nix
from our system:
outputs = { nixpkgs, home-manager, neovim-flake, ... }@inputs: {
# NixOS configuration entrypoint
# Available through 'nixos-rebuild --flake .#your-hostname'
nixosConfigurations = {
# FIXME replace with your hostname
nixos = nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; }; # Pass flake inputs to our config
# > Our main nixos configuration file <
modules = [ ./nixos/configuration.nix ];
};
};
Let's add the neovim-flake.defaultPackage.${system}
into our configuration.nix
list of packages:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
# ...
neovim-flake.defaultPackage.${pkgs.system}
];
# ...
}
Nope! After trying to rebuild it we get again: error: undefined variable neovim-flake
so GPT was kinda wrong about this. Let's investigate this issue again in the configuration.nix
. Hmm I still don't understand why would I declare the neovim-flake
into my configuration.nix
when this line in flake.nix
says specialArgs = { inherit inputs; }; # Pass flake inputs to our config
so what's the issue here?
I forgot to update the flake
I completely forgot to do the nix flake update
this whole time and only did the sudo nixos-rebuild switch --flake .#hostname
. What happens now when I run both commands?
❯ nix flake update
warning: updating lock file '/home/stablejoy/nix-config/flake.lock':
• Updated input 'home-manager':
'github:nix-community/home-manager/72ce74d3eae78a6b31538ea7ebe0c1fcf4a10f7a' (2023-02-20)
→ 'github:nix-community/home-manager/5160039edca28a7e66bad0cfc72a07c91d6768ad' (2023-04-20)
• Removed input 'home-manager/utils'
• Updated input 'nixpkgs':
'github:nixos/nixpkgs/bb2009ca185d97813e75736c2b8d1d8bb81bde05' (2023-04-19)
→ 'github:nixos/nixpkgs/ba0027bc70ae3294250cb662516b6571c3f406c9' (2023-04-20)
[37.1 MiB DL]error: insufficient permission for adding an object to repository database .git/objects
fatal: cannot create an empty blob in the object database
error: program 'git' failed with exit code 128
(use '--show-trace' to show detailed location information)
Great! Another error! Do I have to use sudo
with flakes? I thought not?
if you're updating a flake that is managed system-wide and owned by the root user (such as when using flakes for your NixOS system), you might need to use sudo to update the lock file.
After using the sudo
with sudo nix flake update
and trying the rebuild command now the system is fetching another gigabyte of packages. Why? It is fetching llvm
and ark
for example. Let's see what comes after this. The reason for this is probably that I forgot to even update the flake in the first place, I don't even remember now after all this error hunting. By watching the running output it seems it is rebuilding Plasma DE too and on top of that it is building something from source so it is taking some time now already.
OK, it's been over an hour or so and it is still building the whole source of Plasma DE, currently at 61% build phase. I'm now really confused. I have enabled flakes but somehow I still do not understand flakes. Why isn't this using a binary cache, why is it building from source? On top of that it is building firefox from source which is a nightmare. I have to think what to do next and read more about flakes. I think I will stop the compilation process because it is only making my system slow at the moment.
Top comments (0)