我在
nvm
中定义了一个 bash 函数 /root/.profile
。当我在 docker build
步骤中调用该函数时,RUN
未能找到该函数。
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
错误是
Step 5 : RUN nvm install 0.12
---> Running in b639c2bf60c0
/bin/sh: nvm: command not found
我设法通过用
nvm
包裹它来调用 bash -ic
,这将加载 /root/.profile
。
RUN bash -ic "nvm install 0.12" && \
bash -ic "nvm alias default 0.12" && \
bash -ic "nvm use 0.12"
上面的方法工作正常,但是有一个警告
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
我想知道是否有一种更简单、更干净的方法来直接调用 bash 函数,因为它是普通的二进制文件,而不需要
bash -ic
包装?也许类似
RUN load_functions && \
nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12
Docker 的
RUN
不会在 shell 中启动命令。这就是为什么 shell 函数和 shell 语法(如 cmd1
&& cmd2
)不能开箱即用的原因。您需要显式调用 shell:
RUN bash -c 'nvm install 0.12 && nvm alias default 0.12 && nvm use 0.12'
如果您害怕那么长的命令行,请将这些命令放入 shell 脚本中并使用
RUN
: 调用该脚本
脚本.sh
#!/bin/bash
nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12
并使其可执行:
chmod +x script.sh
在 Dockerfile 中放入:
RUN /path/to/script.sh
在 nvm 的特殊情况下,我使用以下内容:
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 \
"
第一个命令 (
ADD --link ...
) 会将 NVM 从 GitHub 安装到容器中(您需要定义 ARG NVM_DIR 和 NODE_VERSION 或仅替换代码片段中的占位符)。
ADD 将避免将 Git 安装到容器本身中。
第二个命令将实例化 Bash shell 并导入和使用 nvm.sh 中的函数定义。