NixOS Configurations in Isolation

Hi everyone,

TL;DR: In what ways, if there are any, is it possible for multiple nix configurations be run both simultaneously and in isolation?

When reading about nix, I felt optimistic that it could solve a persistent problem I’m trying to solve, but I so far I’ve had no luck finding a clear answer on the forums. Does anybody know if it’s possible to simultaneously run several configurations or sub configurations independently from each other - as in personal and work related configurations should be kept independent and separate?

I use my computer for different activities (school, work, personal, etc.). I want to produce these environments in relative isolation because each environment contains a theme of packages and configurations that I do not want interfering with the others. For example, if the work environment heavily relies on plasma and the school environment uses river, I do not want plasma settings, configurations, programs, etc. to interfere with the setup for the personal environment and vice versa. Each environment has a different purpose and everything in it is tilted towards that purpose. Additionally, I am trying to get each environment to be completely independent from the others such that if I moved the environment onto another computer it would not stop working because it secretly relied on something another environment provided. I understand this is one of the main selling points of nix?

Currently, I have come close to this goal by creating a directory and shell.nix file for each environment. Then nix-shell --pure can be used to switch into it. Setting the home directory to environment directory in the shell file helped to keep the configuration files separate. It’s not easy though to modify and reload the shell environment from within itself without dropping into a subshell. Exiting the shell closes all the open programs in that environment, so that is really not an option either. Also, I cannot figure out how to add plasma to one of the shells.

After trying to use shells as environments, I set up a series of configuration files for the different environments, but I cannot figure out how to get them to work with a multi-user system or when trying to use different environments on different TTYs for example. I feel like I am close to getting everything working, but am missing a small but important piece.

I have looked some into nix profiles, nix shells, nix containers, nix direnv, home-manager, flakes etc., but struggle to get them working in line with my goal - probably because, while I have lots of Linux experience, Nix is completely new to me. I am assuming that nix containers would probably be the most obvious choice, but are there other solutions with less overhead that achieve the same thing? What are my options when trying to use multiple configurations at the same time in isolation using any of these options?

Essentially, the final question is, before I spend days or weeks learning this new system, would anybody be able to tell me if this is possible with nix and perhaps be so kind as to point me in the right initial direction?

Thank you for your help.

To me, this suggests two users, each with their own Home Manager configuration, that you switch between when you want to change contexts, and with as few programs as possible installed via the shared NixOS configuration. Would that work for you?

3 Likes

Thank you for the quick response!

Home manager is very similar to what I am trying to achieve, and maybe using multiple users would be a trick to use multiple home-manager configurations at once. It’s definitely outside of the box, and I guess I could quickly switch between users with su without having to log in and out of users. Then I can also try symlinking some of the shared non-dotfile home directories between the users. I’ll try that and report back if I have any updates.

Are there any tools that would allow me to, from one configuration, drop into a shell utilizing another configuration without switching users though?

If you’re using flakes, and have defined multiple home-manager configurations (and installed HM as standalone), you should be able to just do:

home-manager switch --flake <path-to-flake>#my-work-home

EDIT: I re-read your message. That won’t necessarily drop you into a shell with the new config though but it will symlink all the packages/configs into your current shell.

1 Like

I don’t think I really understand your requirements. It seemed like you wanted to run entirely different desktop environments, and so I think you’d need to be very precise about what you do and don’t want shared if you ‘drop into’ the other one. Things like D-Bus, screensavers, clipboards, etc. tend to assume that one user runs one DE at a time, and there’s not much Nix can do about that. You can be isolated, in which case any programs you run in the nested environment won’t be well-integrated into your host shell; or you can be shared, in which case I don’t get why you’re going to all the trouble to keep your peas and carrots separate—just use per-project shells like most of us, and maybe nix-direnv for convenient and automatic switching between them on every cd.

3 Likes

I would say no, unless your home is more or less stateless. Most user-level programs including DEs, browsers, etc. will dump their data and config into $HOME, that will be persisted and available to the program unless you switch users.

1 Like

If you’re using flakes, and have defined multiple home-manager configurations (and installed HM as standalone), you should be able to just do:

home-manager switch --flake <path-to-flake>#my-work-home

Thanks for the response. I could drop into a separate shell manually before switching to the flake though, right? I was only thinking a separate shell because I didn’t want processes in the initial shell to be removed from the environment, but I don’t know how Nix handles running programs whose packages are removed from the environment. Except switching to the flake wouldn’t be the “pure” like nix-shell --pure would be, right? But I could use shell.nix to switch to the flake from within a pure nix-shell and use direnv to reload the shell, or does that sound to you like something that will cause issues?

Nix doesn’t handle it, the shell (bash) does. Nix just sets some envvars like PATH and so on. After that point there’s nothing for nix to worry about (other than it will generally not garbage collect running programs if you run a gc).

And using home-manager to switch between configs on the same user wouldn’t really work for your use case, if we’re talking about entirely different compositors for example. You’d still have to log out and in.

1 Like

I don’t think I really understand your requirements. It seemed like you wanted to run entirely different desktop environments, and so I think you’d need to be very precise about what you do and don’t want shared if you ‘drop into’ the other one. Things like D-Bus, screensavers, clipboards, etc. tend to assume that one user runs one DE at a time, and there’s not much Nix can do about that. You can be isolated, in which case any programs you run in the nested environment won’t be well-integrated into your host shell; or you can be shared, in which case I don’t get why you’re going to all the trouble to keep your peas and carrots separate—just use per-project shells like most of us, and maybe nix-direnv for convenient and automatic switching between them on every cd.

You’re right, I am wanting to run entirely different desktop environments, and I think your first reply might be on point, but essentially I am concerned about aspects of each desktop environment being isolated.

If it isn’t part of the desktop environment, I’ll just put it in the system configuration. Changing the user home directory ($HOME) can take care of configuration files not overlapping as far as I can tell, and I often run multiple window managers at once as one user so that’s possible at least. D-Bus, screensavers, clipboards, dotfiles, wallpapers, etc. are all part of the desktop environment, so ideally they would be isolated with that environment. I am not trying to turn each desktop environment into Virtualbox’s seamless mode - as cool as that would be.

I am only wanting to create reproducible desktop environments that I can install, or not install, on different computers, but I want to be able to use and develop them all on the same system without concerning myself with them potentially having dependencies (like fonts) outside the defined configuration for them. Then, later, I can use the configurations to provision a new computer based on what the computer’s specifications are and for what it is going to be immediately used. Dotfiles have dependencies that are very hard to keep track of, and that is the issue I have been having with maintaining my current setup.

That seems like a potential use case for the nix-direnv project you suggested after looking through the repository page, and I’m guessing it will still work even for a desktop environment?

I would say no, unless your home is more or less stateless. Most user-level programs including DEs, browsers, etc. will dump their data and config into $HOME, that will be persisted and available to the program unless you switch users.

Switching users is seeming like an increasingly viable option, especially since I can should be able to set it up to switch shells quickly with su. The other option I was considering would be switching the $HOME environment variable in the configuration file to something like /home/username/Environments/School so that all the caches, databases, and such generated by programs in that environment would be located there instead of in /home/username.

Nix doesn’t handle it, the shell (bash) does. Nix just sets some envvars like PATH and so on. After that point there’s nothing for nix to worry about (other than it will generally not garbage collect running programs if you run a gc).

And using home-manager to switch between configs on the same user wouldn’t really work for your use case, if we’re talking about entirely different compositors for example. You’d still have to log out and in.

That makes sense, thanks for the insight. I have noticed that you can launch Wayland compositors inside of other Wayland compositors. For example, I can launch Wayfire inside of Kwin, maximize it, and use it like normal, though that’s really not what I am trying to do here. When I am talking about switching environments, I am generally envisioning switching TTYs, logging in, and switching to an environment from there.