NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.88k stars 1.53k forks source link

Can't find nix-env after source nix.sh #8269

Closed liketoeatcheese closed 1 year ago

liketoeatcheese commented 1 year ago

Platform

Dockerfile: fedora:latest (tried with fedora:37 and fedora:38, same error)

Additional information

Here's the Dockerfile content, nothing fancy:

FROM fedora:37
RUN sudo dnf install -y man man-pages cargo bash curl git passwd python3 python3-pip procps-ng iputils iproute findutils ncurses vi vim && \
dnf reinstall -y shadow-utils && \
grep -v nodocs /etc/dnf/dnf.conf | sudo tee /etc/dnf/dnf.conf
RUN useradd -G wheel user && \
chown -R user:user /home/user
RUN sudo dnf install -y xz && \
sudo mkdir -p /nix /etc/nix  && \
sudo chmod a+rwx /nix && \
sudo echo 'sandbox = false' > /etc/nix/nix.conf
USER user
RUN python3 -m pip install --user ansible
RUN touch ~/.bash_profile
RUN curl -L https://nixos.org/nix/install | sh && \
source /home/user/.nix-profile/etc/profile.d/nix.sh && \
nix-env -iA nixpkgs.bat
USER root
WORKDIR /home/user
COPY ./fem.yml/ /home/user/ansible/fem.yml
RUN chown -R user:user /home/user/
USER user
CMD ["bash"]

As you can see, I clearly sourced the file using source /home/user/.nix-profile/etc/profile.d/nix.sh, please note that I also tried to source it using . /home/user/.nix-profile/etc/profile.d/nix.sh. You can replicate it by using the docker file.

................
#10 12.92 building '/nix/store/dmbv9wmw5b8lmh17ik4m0an9ih8xbbzf-user-environment.drv'...
#10 23.08 unpacking channels...
#10 28.63 modifying /home/user/.bash_profile...
#10 28.63
#10 28.63 Installation finished!  To ensure that the necessary environment
#10 28.63 variables are set, either log in again, or type
#10 28.63
#10 28.63   . /home/user/.nix-profile/etc/profile.d/nix.sh
#10 28.63
#10 28.63 in your shell.
#10 28.66 /bin/sh: line 1: nix-env: command not found
------
executor failed running [/bin/sh -c curl -L https://nixos.org/nix/install | sh && source /home/user/.nix-profile/etc/profile.d/nix.sh && nix-env -iA nixpkgs.bat]: exit code: 127

However, if you start a container from scratch without using Dockerfile, it works: docker run -ti --rm fedora:latest /bin/bash, and then run every command from that Dockerfile, and it will work. But not for the dockerfile

abathur commented 1 year ago

Not sure it'll show anything meaningful, but maybe try invoking set -x (trace) before sourcing it?

liketoeatcheese commented 1 year ago

@abathur , thank you! That helped, but another thing arose.

I added that and it showed these 2 lines:

#10 14.85 + . /home/user/.nix-profile/etc/profile.d/nix.sh
#10 14.85 ++ '[' -n /home/user ']'
#10 14.85 ++ '[' -n '' ']'

Then I added a few more debugging:

RUN curl -L https://nixos.org/nix/install | sh
RUN set -x && \
echo $(whoami) && \
echo $HOME && \
echo $USER && \
ls -la ~ && \
cat /home/user/.nix-profile/etc/profile.d/nix.sh && \
. /home/user/.nix-profile/etc/profile.d/nix.sh && \
nix-env -iA nixpkgs.bat

And then it showed

#10 14.81 Installation finished!  To ensure that the necessary environment
#10 14.81 variables are set, either log in again, or type
#10 14.81
#10 14.81   . /home/user/.nix-profile/etc/profile.d/nix.sh
#10 14.81
#10 14.81 in your shell.
#10 14.85 ++ whoami
#10 14.85 + echo user
#10 14.85 + echo /home/user
#10 14.85 user
#10 14.85 /home/user
#10 14.85
#10 14.85 + echo
#10 14.85 + ls -la /home/user
#10 14.85 total 44
#10 14.85 drwx------ 1 user user 4096 Apr 28 22:16 .
#10 14.85 drwxr-xr-x 1 root root 4096 Apr 28 22:04 ..
#10 14.85 -rw-r--r-- 1 user user   18 Jan  2 11:43 .bash_logout
#10 14.85 -rw-r--r-- 1 user user  279 Apr 28 22:16 .bash_profile
#10 14.85 -rw-r--r-- 1 user user  492 Jan  2 11:43 .bashrc
#10 14.85 drwxr-xr-x 1 user user 4096 Apr 28 22:16 .cache
#10 14.85 drwxr-xr-x 1 user user 4096 Apr 28 22:16 .local
#10 14.85 -rw-r--r-- 1 user user   52 Apr 28 22:16 .nix-channels
#10 14.85 drwxr-xr-x 2 user user 4096 Apr 28 22:16 .nix-defexpr
#10 14.85 lrwxrwxrwx 1 user user   44 Apr 28 22:16 .nix-profile -> /home/user/.local/state/nix/profiles/profile
#10 14.85 + cat /home/user/.nix-profile/etc/profile.d/nix.sh
#10 14.85 if [ -n "$HOME" ] && [ -n "$USER" ]; then
#10 14.85
#10 14.85     # Set up the per-user profile.
#10 14.85
#10 14.85     NIX_LINK="$HOME/.nix-profile"
#10 14.85     if [ -n "${XDG_STATE_HOME-}" ]; then
#10 14.85         NIX_LINK_NEW="$XDG_STATE_HOME/nix/profile"
... The rest of the nix.sh file with the error

Based on what I saw on the script, it's checking if $HOME and $USER exist, so I added the echo $HOME and echo $USER commands in for debugging. $HOME exist but $USER doesn't. Which is kinda odd. But to fix the error I added $USER environment variable:

RUN curl -L https://nixos.org/nix/install | sh
ENV USER=user
RUN . /home/user/.nix-profile/etc/profile.d/nix.sh && \
nix-env -iA nixpkgs.bat

Another thing that came up is that after the image was built, and I ran it with "docker run --rm -it basefedora:1.0 bash", the container didn't source it, and I have to manually put it in . /home/user/.nix-profile/etc/profile.d/nix.sh. I tried to overcome this by adding CMD, hopinh this should run every time the container starts up:

CMD ["bash","-c",". /home/user/.nix-profile/etc/profile.d/nix.sh"]
CMD ["bash"]

But it didn't work, which is weird. Any thoughts?

abathur commented 1 year ago

I did notice someone else doing more user setup in another Dockerfile that runs the installer. Didn't realize it was significant at the time, but it converged on something similar: https://github.com/whacked/setup/blob/787b81cd334f3db462ea22e8939b9a393c83db95/nix/Dockerfile#L18-L33C12

But it didn't work, which is weird. Any thoughts?

Not certain. I don't Dockerfile much. It makes sense that the bare one wouldn't work, since I think the *rc files are run for interactive sessions. I see one using bash -l (https://github.com/coq-community/hydra-battles/blob/62ab1fc4574818258a46d132db78c042936ea5c9/.nix/gitpod.Dockerfile#L35) which might work (as might bash i). Your first example is probably failing because it's just running bash in command mode which will terminate. (It probably did source OK, but didn't leave a running shell to connect to?)

liketoeatcheese commented 1 year ago

I did notice someone else doing more user setup in another Dockerfile that runs the installer. Didn't realize it was significant at the time, but it converged on something similar: https://github.com/whacked/setup/blob/787b81cd334f3db462ea22e8939b9a393c83db95/nix/Dockerfile#L18-L33C12

@abathur, thanks again! You pointed me to the correct place :) Saw line 34 of that link, and realized I just need to set this up in the .bashrc of the user and it works fine. The odd thing is that it should already be done in the install script. But maybe Dockerfile is different

RUN echo '. $HOME/.nix-profile/etc/profile.d/nix.sh' | tee -a $HOME/.bashrc | tee -a $HOME/.bash_profile