# Strategy to use same config at work and home

**URL:** https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317
**Category:** Help
**Created:** [October 18, 2023, 2:13pm UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317 "2023-10-18T14:13:20Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![mmartinortiz](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mmartinortiz](https://discourse.nixos.org/u/mmartinortiz)
#### Post date: [October 18, 2023, 2:13pm UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/1 "2023-10-18T14:13:20Z")

</div>

Hi,

I’m quite new to Nix, but I managed to create my own “dotfiles” with Home Manager and I’m quite happy with the tooling I managed to setup.

Now I’d like to take this with me at my work computer. Most of my configuration is fine, except for:

- Git: Different user, email and secret management
- Home: Different user and home folder
- Fish Shell: Extend with new alias

What would be a good way to achieve this? I though about creating a new repository for my work configuration (in the company’s space) or just extending my personal configuration with a new user and load the Git configuration from a company’s repository.

Suggestions? Any example I could look to get inspired?

Thanks

---

<div class="post-metadata">

### Author: ![Jerith](https://discourse.nixos.org/user_avatar/discourse.nixos.org/jerith/32/246_2.png) [@Jerith](https://discourse.nixos.org/u/Jerith)
#### Post date: [October 20, 2023, 12:09pm UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/2 "2023-10-20T12:09:19Z")

</div>

I haven’t taken the plunge into home manager yet, but I’ve done this with my `/etc/nixos/configuration.nix`.

My approach is to keep my configuration in a git repo, with clones on my home and work machines.

I have an import like `adminInfo = import ./admin-info.nix {};` in `configuration.nix`. And I have two files in the repo:

`home-admin-info.nix`:

```nix
{}:

{
  user = "matt";
  hostName = "alpha";
  domain = "mchenryfamily.org";
}

```

`work-admin-info.nix`:

```nix
{}:

{
  user = "mmchenry";
  hostName = "mmchenry-nixos";
  domain = "work.com";
}

```

The only thing that’s not version controlled in git is the `admin-info.nix` symlink, which points to the appropriate `*-admin-info.nix` on each machine.

Then elsewhere in `configuration.nix`, I can refer to these variables, e.g. `networking.hostName = adminInfo.hostName`.

I also have `hardware-configuration.nix` symlinked to `home-hardware-info.nix` or `work-hardware-info.nix`, since the machines need different kernel modules etc.

---

<div class="post-metadata">

### Author: ![lilyball](https://discourse.nixos.org/user_avatar/discourse.nixos.org/lilyball/32/939_2.png) [@lilyball](https://discourse.nixos.org/u/lilyball)
#### Post date: [October 20, 2023, 11:52pm UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/3 "2023-10-20T23:52:07Z")

</div>

I use a single flake for everything. The flake has a separate configuration for each machine, and every machine has its own module which is given to `mkSystem` (I don’t use home-manager independently of NixOS/nix-darwin but I assume you can set a per-host configuration). The module I use for each host follows the same structure, which is a file `hosts/$hostname/default.nix`. A sample host file might look like

```nix
{ config, lib, pkgs, ... }:

with lib;

{
  imports = [
    # import the arch-os file
    ../x86_64-darwin.nix
  ];

  # per-host user overrides
  home-manager.users.lily.imports = [./home/lily];

  # this is a work machine, I have a module for that
  my-work-internal.enable = true;

  # hardware-specific stuff
  security.pam.enableSudoTouchIdAuth = true;

  # every host sticks with the state version current when I set it up
  system.stateVersion = 4;
}

```

This one is for nix-darwin but my NixOS hosts are structured the same way. The `x86_64-darwin.nix` file then imports a `./darwin.nix` file, and that sets a bunch of defaults that I want to apply to all of my macOS machines and imports `../common/darwin`. That’s the entry-point into my modules for darwin, there’s a similar `common/nixos`, and both of them import the shared `common/default.nix`. The difference between `hosts/darwin.nix` and `common/darwin` is the former only sets options (often with `mkDefault` so hosts can override easily) and the latter defines options.

The point of this setup is I’ve got as much shared between NixOS and nix-darwin as possible, as much shared between hosts as possible, and there’s a clear place to look for anything. I have all of my user config in `common/users/$username`, which is mostly home-manager config. I also define shared modules for home-manager in `common/home-manager` so I can reuse stuff between users as much as possible.

I do use the same username everywhere, but because I have separate files for the OS-level user configuration and the home-manager config, if I need to change usernames for one machine I can just define a separate user that imports the same config, but I haven’t needed that yet. Or I suppose I could define an OS-level “username” option that I can override per-host to get an identical setup with a different username.

I also make liberal use of the idea of defining new modules that have an `enable` option and set a bunch of stuff, so I can just turn sections of my config on or off on a per-host basis. I did this mostly so that way I can share my config to a headless raspberry pi and easily turn off anything that I don’t need in that minimal environment (such as direnv, or the set of tools I use for Rust development).

---

<div class="post-metadata">

### Author: ![mmartinortiz](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/ecae2f/32.png) [@mmartinortiz](https://discourse.nixos.org/u/mmartinortiz)
#### Post date: [October 22, 2023, 10:36am UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/4 "2023-10-22T10:36:48Z")

</div>

Thanks for you answer!

Both approaches are interesting. The use of a symlink makes it easy to have the local clone work for different scenarios; using different modules is a bit harder for me to understand (I will have to read more about `mkDefault`) but I grasp the idea behind it.

I also found [this other approach](https://github.com/nix-community/home-manager/issues/3075#issuecomment-1593969080) with Home manager.

At work I know that they prefer that my “work” setup is not part of my public setup. How would you organize that?

---

<div class="post-metadata">

### Author: ![keysmashes](https://discourse.nixos.org/user_avatar/discourse.nixos.org/keysmashes/32/5266_2.png) [@keysmashes](https://discourse.nixos.org/u/keysmashes)
#### Post date: [October 22, 2023, 12:14pm UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/5 "2023-10-22T12:14:25Z")

</div>

> [@mmartinortiz](#):
>
> At work I know that they prefer that my “work” setup is not part of my public setup. How would you organize that?

This is addressed by my solution – I have one flake for each system I use (personal, work, servers, etc.) and one flake for common configuration that they all have as an input. The result is that I can make the common configuration flake public (it’s [sersorrel/sys](https://github.com/sersorrel/sys)), whilst leaving the actual system flakes (based on the template [sersorrel/sys-tem](https://github.com/sersorrel/sys-tem)) private.

It has some downsides (have to manually update each system flake separately, mixing nixpkgs versions makes writing the common flake very annoying, and it’s almost impossible to test every machine flake before committing updates to the common flake), but being able to make only parts of my configuration public is important for me, so it feels like it’s worth it.

---

<div class="post-metadata">

### Author: ![nrdxp](https://discourse.nixos.org/user_avatar/discourse.nixos.org/nrdxp/32/8501_2.png) [@nrdxp](https://discourse.nixos.org/u/nrdxp)
#### Post date: [October 23, 2023, 4:22am UTC](https://discourse.nixos.org/t/strategy-to-use-same-config-at-work-and-home/34317/6 "2023-10-23T04:22:56Z")

</div>

To solve for situations like this, I export multiple different module for each software component I use. So instead of having everything in one monolithic profile, I have my zsh setup in one module, my preferred editor config in another, etc, etc.

Then I have several options. My personal flake exports multiple systems that I use, my home desktop workstation, my laptop, etc. These systems import the modules they want to use directly from within this public flake.

However, I have some work machines which are not public but I still use some of my public profiles individually by consuming my public flake as an input and simply importing my desired profiles as you would any other module. A contrived example:

```auto
# private work flake
{
  # inputs elided
  outputs = inputs: {
    nixosConfigurations.myWork = inputs.nixpkgs.nixosSystem {
      modules = [
        inputs.myPublicFlake.nixosModules.zsh
        # whatever else I want to import from `myPublicFlake`
        ./private-in-repo-module.nix
      ];
    };
  };
}
```
