Dockerfile ARG和ENV中的shellexpression式的默认值

我想接收版本号作为单个参数,并在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}... 

如果我尝试了上面的内容,shellexpression式不会被评估,只是在后来的RUN脚本中被粘贴。

有没有更好的方法来实现这一点,而不创build一个外部的shell脚本包装这个Dockerfile?

从文档:

$ {variable_name}语法还支持一些标准的bash修饰符,如下所示:

$ {variable:-word}表示如果设置了variables,则结果将是该值。 如果variables没有设置,则字将是结果。

$ {variable:+ word}表示如果设置了variables,那么word将是结果,否则结果是空string。

ENV是特殊的docker build命令,不支持这个。 你正在寻找的是在ENV中运行Shell命令。 所以这是行不通的。

可能的解决scheme是使用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参数/环境