Dockerfile ARG和ENV中带有shell表达式的默认值

时间:2017-09-04 07:13:02

标签: shell docker dockerfile

我希望将版本号作为单个参数接收,并在Dockerfile中的RUN脚本中提取URL中各个位置的主要/次要编号。

ARG CUDA_VERSION
ARG CUDNN_VERSION

ENV CUDA_FULL="${CUDA_VERSION:-8.0.61_375.26}" \
    CUDA_MAJOR="$(echo ${CUDA_VERSION:-8.0.61_375.26} | cut -d. -f1)" \
    CUDA_MINOR="$(echo ${CUDA_VERSION:-8.0.61_375.26} | cut -d. -f2)" \
    CUDA_MAJMIN="$CUDA_MAJOR.$CUDA_MINOR"
ENV CUDNN_FULL="${CUDNN_VERSION:-7.0.1}" \
    CUDNN_MAJOR="$(echo ${CUDNN_VERSION:-7.0.1} | cut -d. -f1)" \
    CUDNN_MINOR="$(echo ${CUDNN_VERSION:-7.0.1} | cut -d. -f2)" \
    CUDNN_MAJMIN="$CUDNN_MAJOR.$CUDNN_MINOR"

RUN curl -LO https://.../${CUDNN_FULL}/.../...${CUDA_MAJMIN}...

如果我尝试上述操作,则不会评估shell表达式,只是在以后的RUN脚本中按原样粘贴。

有没有更好的方法来实现这一点,而无需创建包装此Dockerfile的外部shell脚本?

1 个答案:

答案 0 :(得分:3)

来自文档:

  

$ {variable_name}语法还支持以下指定的一些标准bash修饰符:

     

$ {variable:-word}表示如果设置了变量,那么结果将是该值。如果未设置变量,那么word将是结果。

     

$ {variable:+ word}表示如果设置了变量,那么word将是结果,否则结果是空字符串。

ENV是特殊的docker build命令,并不支持此功能。您正在寻找的是在ENV中运行Shell命令。所以这不会起作用。

可能的解决方案是使用bash脚本

<强> cuda_version.sh

#!/bin/bash
CUDA_FULL="${CUDA_VERSION:-8.0.61_375.26}"
CUDA_MAJOR="$(echo ${CUDA_VERSION:-8.0.61_375.26} | cut -d. -f1)"
CUDA_MINOR="$(echo ${CUDA_VERSION:-8.0.61_375.26} | cut -d. -f2)"
CUDA_MAJMIN="$CUDA_MAJOR.$CUDA_MINOR" 
CUDNN_FULL="${CUDNN_VERSION:-7.0.1}"
CUDNN_MAJOR="$(echo ${CUDNN_VERSION:-7.0.1} | cut -d. -f1)"
CUDNN_MINOR="$(echo ${CUDNN_VERSION:-7.0.1} | cut -d. -f2)"
CUDNN_MAJMIN="$CUDNN_MAJOR.$CUDNN_MINOR"

将dockerfile更改为

ARG CUDA_VERSION=8.0.61_375.26
ARG CUDNN_VERSION=7.0.1

ENV CUDA_VERSION=${CUDA_VERSION} CUDNN_VERSION=${CUDNN_VERSION}
COPY cuda_version.sh /cuda_version.sh
RUN bash -c "source /cuda_version.sh && curl -LO https://.../${CUDNN_FULL}/.../...${CUDA_MAJMIN}..."

您可以从shell文件中删除默认值,因为它们将始终存在于Dockerfile参数/环境中