22

I have a bash function nvm defined in /root/.profile. docker build failed to find that function when I call it in RUN step.

RUN apt-get install -y curl build-essential libssl-dev && \
    curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh
RUN nvm install 0.12 && \
    nvm alias default 0.12 && \
    nvm use 0.12

The error is

Step 5 : RUN nvm install 0.12
 ---> Running in b639c2bf60c0
/bin/sh: nvm: command not found

I managed to call nvm by wrapping it with bash -ic, which will load /root/.profile.

RUN bash -ic "nvm install 0.12" && \
    bash -ic "nvm alias default 0.12" && \
    bash -ic "nvm use 0.12"

The above method works fine, but it has a warning

bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell

And I want to know is there a easier and cleaner way to call the bash function directly as it's normal binary without the bash -ic wrapping? Maybe something like

RUN load_functions && \
    nvm install 0.12 && \
    nvm alias default 0.12 && \
    nvm use 0.12
5
  • RUN bash -c 'nvm install 0.12 && nvm alias default 0.12 && nvm use 0.12' should do the trick. Does it work for you? (I'm not 100% sure because I don't know how your container is looking in detail) Commented Sep 22, 2015 at 3:24
  • It works fine. But I am looking for a better solution. Commented Sep 22, 2015 at 3:28
  • Ok, check my answer. A shell script is the cleanest way to do it. Commented Sep 22, 2015 at 3:32
  • You've not accepted my answer so far. What do you mean with a better solution? Commented Sep 22, 2015 at 5:02
  • NVM is not designed for Docker. Do you really want two Node.js in a single container? Commented Nov 8, 2016 at 5:39

2 Answers 2

19

Docker's RUN doesn't start the command in a shell. That's why shell functions and shell syntax (like cmd1 && cmd2) cannot being used out of the box. You need to call the shell explicitly:

RUN bash -c 'nvm install 0.12 && nvm alias default 0.12 && nvm use 0.12'

If you are afraid of that long command line, put those commands into a shell script and call the script with RUN:

script.sh

#!/bin/bash

nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12

and make it executable:

chmod +x script.sh

In Dockerfile put:

RUN /path/to/script.sh
Sign up to request clarification or add additional context in comments.

8 Comments

I need run nvm in some different steps. And I think the right quote of bash -c is hard to control when commands are formatted as multiple lines.
That's why I've suggested to use a shell script.
I don't get why you need multiple scripts. Can you elaborate on that? Once I got it I may suggest something.
This is not what I got from documentation: "RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)".
yeah I am not sure this answer is right...I was under the impression that each RUN command executed its contents in a subshell.
|
0

In the very specific case of nvm, I use the following:

ADD --link  https://github.com/nvm-sh/nvm.git#${NVM_VERSION} $NVM_DIR

RUN /bin/bash -c "\
    source ${NVM_DIR}/nvm.sh \
    && nvm install -b --no-progress $NODE_VERSION \
    && nvm alias default $NODE_VERSION \
    && nvm use default \
    "

The first command (ADD --link ...) will install NVM from GitHub into the container (you need to either define the ARGs NVM_DIR and NODE_VERSION or just replace the placeholders in the snippet). ADD will avoid having to install Git into the container itself.

The second command will instantiate a Bash shell and import & use the function definitions from nvm.sh.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.