Skip to content

Declarative and reproducible Linux environments using Nix and Home-Manager

License

Notifications You must be signed in to change notification settings

99linesofcode/home-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

86 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Home-Manager

My flake based standalone home-manager configuration. While I run NixOS on all of my systems I prefer using Home Manager so it can be used irrespective of the Linux operating system.

How to Use

Home-manager is a Nix powered tool and while knowledge of Nix, the Nix Module System and Nix Flakes will make your life a lot easier, I've set up this repository in such a way that you should be able to get up and running in no time. I've made a conscious effort to stay away from libraries such as flake-utils to keep things simple and remain as close to the Nix language as possible.

To start using this repository to manage your own dotfiles with Nix, there are only a couple of things you need to do:

  1. Make sure that your system has both Nix and Home Manager installed;
  2. Define a HomeConfiguration for your host and user;
  3. Add a custom user configuration under hosts/;
  4. Configure your user and enable any Nix Modules found in modules/ that you would like to use;
  5. Add encrypted secrets if you are using any modules that depend on SOPS;
  6. Activate your configuration.

Defining a HomeConfiguration

The HomeConfiguration function is defined in flake.nix. Outputs returns an attribute set with homeConfigurations containing one or more HomeConfiguration. Below you can find an example of the one I use for the host luna and username shorty:

home-manager/flake.nix

Lines 58 to 66 in 50fff4a

"luna.shorty" = HomeConfiguration {
extraSpecialArgs = {
inherit inputs outputs;
hostname = "luna";
username = "shorty";
fullName = "Jordy Schreuders";
email = "[email protected]";
role = "workstation";
};

The hostname, username and role arguments passed as extraSpecialArgs are used to determine which hosts/{hostname}/role/{role}/ and hosts/{hostname}/users/{username}/ configuration will get used.

Add a user configuration

The HomeConfiguration function automatically imports hosts/. default.nix is used as a default file when importing directories:

imports =
[
./shared
]
++ existing-imports [
./${hostname}
./${hostname}.nix
];

As you can see this file imports the shared/ and the hosts/{hostname}/ directories which in turn contain their own default.nix files with their own import logic. Every one of these files is in and of itself nothing but a simple Nix module.

Configure your user and enable Nix modules

Reusable modules that have already been built live in the modules/ directory. Most of them are pretty straightforward and consist of a simple mkEnableOption and the relevant module config. Let's look at a simple example:

{
config,
lib,
pkgs,
...
}: let
cfg = config.host.dunst;
in
with lib; {
options = {
host.dunst.enable = mkEnableOption "dunst notifications manager";
};
config = mkIf cfg.enable {
home.packages = with pkgs; [
libnotify
];
services.dunst = {
enable = true;
};
};
}

Enabling this module is as easy as adding home.dunst.enable = true; to your user's configuration. Take a look at hosts/luna/users/shorty/default.nix for a complete example.

Encrypted secrets

Secrets such as your SSH keys, configuration files containing authentication tokens or anything else you might want to hide from the outside world and restrict access to are encrypted and managed through SOPS. Decrypting, storing and using them within Nix is done through https://github.com/Mic92/sops-nix.

The .sops.yaml file configures the public keys that will be used to encrypt files in certain directories:

home-manager/.sops.yaml

Lines 2 to 20 in 50fff4a

keys:
- &master age1nww8elvlr7l2sn2452z6wef8tyex53ehrypemkxhzfay2t99x52scwsw94
- &luna_shorty age1j3xmhg63j8xulauzaqy5ndu4rsvmy6r287mg8aa3ehsfuzdppcfq6y6r7c
creation_rules:
- path_regex: hosts/shared/secrets/.*
key_groups:
- age:
- *master
- *luna_shorty
- path_regex: hosts/luna/secrets/.*
key_groups:
- age:
- *master
- *luna_shorty
- path_regex: hosts/luna/users/shorty/secrets/.*
key_groups:
- age:
- *master
- *luna_shorty

As you can see I've configured both the master and luna_shorty keys to be able to encrypt (and decrypt) files under hosts/shared/secrets/, hosts/luna/secrets/ and hosts/luna/users/{username}/secrets/.

Everytime you use sops to create a file inside one of these directories they will automatically be encrypted with the referenced public keys. Either private key corresponding to one of the public keys can then be used to decrypt the file. Be sure to check out the SOPS repository to learn more.

Now that we've encrypted our secrets, the last step is to learn how to use them inside your Nix modules. SOPS supports a variety of formats but here is an example of how to import a binary file and expose it to your Nix module using the already built in sops-nix library:

sops.secrets = {
"rclone/rclone.conf" = {
format = "binary";
sopsFile = ../hosts/shared/secrets/rclone.conf;
path = config.home.homeDirectory + "/.config/rclone/rclone.conf";
mode = "600";
};
};

When switching to your new configuration, sops-nix will use sops to decrypt the file using the private key stored in $XDG_CONFIG_HOME/sops/age/keys.txt and make it available under XDG_RUNTIME_DIR/secrets.d and, in this case, create a symlink to that file under $HOME/.config/rclone/rclone.conf;.

Activate your configuration

Congratulations, you should now have all the pieces to cobble together your own - declaractive - Linux environment using Nix and Home Manager! Once you're ready to check out your work, simply run the following command and enjoy:

home-manager switch --flake .#{homeConfigAttributeName} where {homeConfigAttributeName} is something like luna.shorty in my examples.

Work In Progress

I've only just started along this journey of Nix myself and there are still quite a few bits and bobs that are missing or a little rough around the edges. For example, some programs might not be bundled with the right module. I'm sure I'll get around to it some day but please be aware that you might run into some issues along the way. If you do, please create a new issue and I'd be happy to help you sort 'em out.

Contributing

Please review our Contribution Guidelines.

Code of Conduct

In order to ensure that the community is welcoming to all, please review and abide by the Code of Conduct.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

License

This software is open source and licensed under the MIT license

About

Declarative and reproducible Linux environments using Nix and Home-Manager

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks