Dockerfile链式构建:FROM继承基础镜像后npm命令无法执行
问题描述
- 开展Docker相关实验时,制作了集成Java与Node运行环境的基础镜像,该镜像已发布至Docker Hub。
- 基于该基础镜像构建下游应用时,编写的Dockerfile内容如下:
FROM quafadas/scala-mill:latest RUN java -version #This doesn't work :-(. RUN npm --version
- 实测直接启动基础镜像容器,在容器内执行
npm --version可正常返回结果,但通过FROM指令继承基础镜像执行下游构建时,RUN npm --version步骤运行失败,报错信息如下:
/bin/sh: npm: command not found 15:15:19 The command '/bin/sh -c npm --version' returned a non-zero code: 127
问题产生原因
该问题由基础镜像的环境变量配置方式,和Docker构建时的命令执行逻辑共同导致:
- 制作基础镜像安装Node/npm时,npm的可执行文件路径仅被添加到了普通用户的个人shell配置文件中(比如普通用户家目录下的
.bashrc、.profile),没有写入全局环境变量配置,也没有将npm可执行文件软链接到/usr/bin、/usr/local/bin这类全局默认PATH目录下。 - 手动启动基础镜像进入交互终端时,默认登录的是配置过PATH的普通用户,shell会自动加载该用户个人配置中的PATH变量,因此可以正常找到npm命令执行。
- Docker执行Dockerfile中的
RUN指令时,默认以root用户身份调用/bin/sh -c执行命令,属于非交互、非登录shell,不会加载普通用户家目录下的个人shell配置,全局PATH中没有包含npm的安装路径,就会触发command not found错误。 - 同文件下
RUN java -version可以正常执行,是因为Java的可执行文件路径默认配置在全局PATH中,root用户执行时也能正常检索到。
验证方式:可以在下游Dockerfile的npm执行步骤前添加RUN echo $PATH,打印出的构建阶段PATH列表中不会包含npm所在的安装目录。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

