【问题标题】:Bad Substitution Error Installing NVM within Debian-based Docker image在基于 Debian 的 Docker 映像中安装 NVM 时出现替换错误
【发布时间】:2016-08-07 16:01:56
【问题描述】:

我正在尝试在我的 Docker 映像上安装 nvm。本来以为这个 Docker 镜像是在 Ubuntu 上构建的,但实际上是在 Debian 上构建的。我正在安装 bash 来 curl NVM,然后安装节点,但我收到 bad substitution 错误:

这是我的 Dockerfile:

FROM docker

RUN apk add --update bash \
  && touch /root/.bashrc \
  && curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash \
  && source /root/.bashrc \
  && nvm install node \
  && npm install

我认为以下错误与&& source /root/.bashrc \ 行有关

=> Downloading nvm as script to '/root/.nvm'

0
=> Appending source string to /root/.bashrc
=> Close and reopen your terminal to start using nvm
/bin/sh: /root/.nvm/nvm.sh: line 107: syntax error: bad substitution
ERROR: Service 'docker' failed to build: The command '/bin/sh -c apk add --update bash   && touch /root/.bashrc   && curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash   && source /root/.bashrc   && nvm install node   && npm install' returned a non-zero code: 2

您知道是什么导致了这个糟糕的替换错误吗?有没有更简单的方法可以在基于 Debian 的 Docker 映像上安装 nvm?感谢您的帮助。

【问题讨论】:

  • 第一步是查看 /root/.nvm/nvm.sh 的第 107 行。

标签: linux bash docker debian dockerfile


【解决方案1】:

Docker 镜像基于 Alpine Linux。 Alpine Linux 使用默认的 shell 作为sh。错误是因为 shbash 不兼容。

很遗憾,NVM 主页上有关于 Alpine Linux 的说明,但非常令人沮丧: nvm on Alpine Linux

经过一些修改,最终版本制作为nvm work with Alpine

FROM docker
RUN apk add --update bash coreutils ncurses tar gzip nodejs \
  && touch ~/.bashrc \
  && curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | sh \
  && LINE=$(cat /root/.nvm/nvm.sh | grep -in '{BASH_SOURCE\[0\]}' | awk -F: '{print $1}') \
  && sed -i "${LINE}s/BASH_SOURCE\[0\]\}/BASH_SOURCE\}\$\{0\}/" /root/.nvm/nvm.sh \ 
  && source ~/.bashrc \
  && nvm ls \
  && nvm install node \
  && nvm use --delete-prefix v6.3.1 \
  && npm install

有点不便,您每次需要使用它时都需要使用nvm use --delete-prefix v6.3.1

我建议也尝试@BMitch 的更新答案。

【讨论】:

  • 我必须在那之后添加RUN rm /usr/bin/node && ln -s /root/.nvm/versions/node/v11.13.0/bin/node /usr/bin/node,否则它将继续使用节点6.7.0
【解决方案2】:

FROM docker 将您的图像基于“Docker in Docker”Alpine 图像。除非您有特殊用例需要 Docker 中的 Docker,否则这可能不是您想要的基础镜像。

如果您需要节点图像,请考虑使用premade node image。这是基于 Debian jessie。

如果您需要基于您的节点安装另一个版本的DebianUbuntu,您可以从这些图像的多个版本中进行选择,例如FROM debian:jessie.


编辑:将 Docker 添加到另一个映像非常容易。这是基于 Debian 的映像的 Dockerfile 条目(appuser 是添加到容器通常运行的其他位置的用户,因此添加了 Docker 组):

ARG DOCKER_GID=999
USER root
RUN curl -sSL https://get.docker.com/ | sh
RUN groupmod -g ${DOCKER_GID} docker && \
    usermod -aG docker appuser

【讨论】:

  • 我相信我确实确​​实想要 Docker 中的 Docker。最终,我需要从 CL 运行 docker 命令来创建基于其他图像的容器。
  • 我已经更新了我的答案,其中包含将 docker 添加到另一个基于 Debian 的映像的步骤。这将避免您遇到的任何阿尔卑斯山问题。
猜你喜欢
  • 2020-09-01
  • 1970-01-01
  • 2020-12-24
  • 2020-03-27
  • 2019-03-08
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多