How can I drop all SSH connections into a Nix development shell

I am trying to use VS Code with with the Remote - SSH extension which runs the GUI on the local machine but interacts with the filesystem and runs all LSPs on the remote. These LSPs usually have system dependencies and I would normally use nix develop and run VS Code from the development shell to provide them but in case of remote server it does not matter how I run the GUI but the server needs to be provided these dependencies the same so I would like to use nix develop to do that too. Unfortunately I am having some trouble getting it to run this way.

I have already tried using the RemoteCommand option in my SSH config and this works perfectly for direct SSH connections from the CLI but I think the Remote extension ignores it so this does not achieve the desired result. I verified this by executing ps -ef on the remote and observing no bash --rcfile ... process like nix develop normally starts.

I think I have to enforce the use of nix develop on the remote system. I have a lot of control over the remote and I can make new users and configure them like I want (except they cannot have root privileges) so I tried making a new user that has exec nix develop ... in its .profile which, once again, works when I connect using CLI but does not when Remote - SSH connects. I can avoid this behavior from the CLI too if I connect like this ssh -t my-host-name 'bash --noprofile --norc' and I assume this is what the extension is doing too because when executing ps I see that it is not using the login shell.

Is there any way I can actually enforce the use of nix develop on the remote machine? If not, how else can I provide certain dependencies to users using Nix (but not NixOS)?

Did you already try append a command to authroized_keys which wraps the executed command and forces it to be in a nix-shell?

1 Like

I haven’t yet. I am curious to see if that works and very grateful for the suggestion but I’ll likely not be touching that system in the following weeks so hopefully you don’t mind to wait to find out if that solves it.

I would like to also let you know that I did come up with a different solution that works and also has one advantage over yours that admittedly, I never asked for in the original post: I made a script that execs nix develop and set it as the login shell. That script also sets $SHELL back to whatever the default shell should be for that user. The advantage here is that normal logins also get nix developed without extra configuration.

Unrelated rant:

Actually found it a bit weird that the “login shell”, or as I would rather call it, “user init”, and the default shell are conceptually tangled. A login shell now makes a lot of sense to be some script or a fancy binary to me but of course this will break anything that expects the “login shell” to be an actual shell, even the chsh can be confusing because you think you are changing the default shell, not the user init process…

I haven’t found any software that actually breaks yet, luckily nix develop uses $SHELL. A google search also reveals that there is no easy way to read the “login shell” from /etc/passwd and everyone suggests using $SHELL instead.