【问题标题】:Pipe RUN's output to ENV in Dockerfile将 RUN 的输出通过管道传输到 Dockerfile 中的 ENV
【发布时间】:2018-04-18 00:30:33
【问题描述】:

我的 Dockerfile 中有以下命令:

RUN echo "\
  export NODE_VERSION=$(\
    curl -sL https://nodejs.org/dist/latest/ |\
    tac |\
    tac |\
    grep -oPa -m 1 '(?<=node-v)(.*?)(?=-linux-x64\.tar\.xz)' |\
    head -1\
  )" >> /etc/bash.bashrc
RUN source /etc/bash.bashrc

以下命令应该将export NODE_VERSION=6.2.2 存储在/etc/bash.bashrc 中,但它没有存储任何内容。

但是,当我在带有 bash 的图像中并手动输入以下命令时,此方法有效。

更新:

我将 shell 从 bash 改回了 Debian/Ubuntu 默认的 dash,这是 POSIX 标准。我删除了这一行:

RUN ln -sf /bin/bash /bin/sh && ln -sf /bin/bash /bin/sh.distrib

比我尝试用export添加到环境变量:

RUN export NODE_VERSION=$(\
  curl -sL https://nodejs.org/dist/latest/ |\
  tac |\
  tac |\
  grep -oPa -m 1 '(?<=node-v)(.*?)(?=-linux-x64\.tar\.xz)' |\
  head -1\
)

但同样,在创建图像时输出丢失,但在我使用$ docker run --rm -it debian /bin/sh 运行图像时有效。为什么?

更新 2:

看起来最终的解决方案应该是这样的:

RUN NODE_VERSION=$( \
  curl -sL https://nodejs.org/dist/latest/ | \
  tac | \
  tac | \
  grep -oPa -m 1 '(?<=node-v)(.*?)(?=-linux-x64\.tar\.xz)' | \
  head -1 \
) && echo $NODE_VERSION

ENV NODE_VERSION $NODE_VERSION

echo $NODE_VERSION 返回 6.2.2,因为它也应该在 Dockerfile 执行时,但 ENV NODE_VERSION $NODE_VERSION 无法读取此内容。有没有办法全局定义变量或如何将RUN 的输出传递给ENV

解决方案:

我最终将 node.js 安装部分放在相同的 RUN 命令下:

RUN NODE_VERSION=$( \
        curl -sL https://nodejs.org/dist/latest/ | \
        tac | \
        tac | \
        grep -oPa -m 1 '(?<=node-v)(.*?)(?=-linux-x64\.tar\.xz)' | \
        head -1 \
    ) \
    && echo $NODE_VERSION \
    && curl -SLO "https://nodejs.org/dist/latest/node-v$NODE_VERSION-linux-x64.tar.xz" -o "node-v$NODE_VERSION-linux-x64.tar.xz" \
    && curl -SLO "https://nodejs.org/dist/latest/SHASUMS256.txt.asc" \
    && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
    && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
    && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
    && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt

【问题讨论】:

  • 这在 Dockerfile 中看起来很乱。为什么不把它放到一个脚本中让容器运行呢?
  • 这对于以下 URL 是必需的:https://nodejs.org/dist/latest/node-v$NODE_VERSION-linux-x64.tar.xz 被解释为 https://nodejs.org/dist/latest/node-v6.2.2-linux-x64.tar.xz 用于 node.js 安装。不幸的是,Node.js 存储库没有提供 https://nodejs.org/dist/latest/node-latest-linux-x64.tar.xz 存档,这将使我的问题变得不必要。
  • 我明白你为什么需要它,但你说它没有存储任何东西,这是否意味着该命令在 Dockerfile 中不起作用?如果是这样,我再次问,为什么不将该命令放在 bash 脚本中以便容器运行?
  • 我试过了,输出还是空的。我正在使用COPY ./node-version.sh /root/ RUN chmod +x $HOME/node-version.sh; /root/node-version.sh

标签: docker dockerfile


【解决方案1】:

更新:
但同样,图像创建时输出丢失,但当我工作时 使用 $ docker run --rm -it debian /bin/sh 运行映像。为什么?

这是因为每个语句(通常以大写动词开头,如RUNADDCOPYENV 等)都是一个全新的中间容器。

这些中间容器不共享环境(例如环境变量),而是一个联合文件系统。也就是说,只有保存在文件系统中的数据和在 Dockerfile 中定义的那些变量(例如通过ENV)通过中间容器传递。如果您想了解 UFS 的工作原理,请查看 this postUnionFS Wiki

如果您的目标是每次构建映像时都安装最新的节点。试试nvm(节点版本管理器)怎么样?

ARG UBUNTU=16.04

# Pull base image.
FROM ubuntu:${UBUNTU}

# arguments
  ARG NVM=0.33.9
  ARG NODE=node

# update apt
  RUN apt-get update

# Install curl
  RUN apt-get install -y curl

# Set home for NVM
  ENV NVM_DIR=/home/inazuma/.nvm

# Install Node.js with NVM
  RUN mkdir -p ${NVM_DIR} && \
    curl -o- https://raw.githubusercontent.com/creationix/nvm/v${NVM}/install.sh | bash && \
    . ${NVM_DIR}/nvm.sh && \
    nvm install ${NODE}

# The first following line should always be called in each intermediate container
# to gain nvm, node and npm command
  . ${NVM_DIR}/nvm.sh && nvm use ${NODE} && \
  npm install -g cowsay && \
  cowsay "Making Docker images is really a headache!"

# Set up your PATH for nvm, node and npm command
  CMD ". ${NVM_DIR}/nvm.sh && nvm use ${NODE} && bash"

请注意,nvm 不会在中间容器之间持续存在,因此您应该使用 . ${NVM_DIR}/nvm.sh 为每个新的中间容器设置 nvm 命令。

NVM 在本地管理 node 二进制文件,使用 nvm use ${NODE} 将 node 和 npm 包含到 PATH 中。在 NVM 中,node 代表最新版本 Node 的别名;因此,我们将NODE 参数设置为node(也可以设置为一串语义版本,如5.09.11.1 等)。

【讨论】:

    猜你喜欢
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多