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

Ach*_*nol 7 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}...
Run Code Online (Sandbox Code Playgroud)

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

如果不创建包装此 Dockerfile 的外部 shell 脚本,是否有更好的方法来实现这一点?

Tar*_*ani 7

从文档:

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

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

${variable:+word} 表示如果设置了variable,则结果为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"
Run Code Online (Sandbox Code Playgroud)

并将您的 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}..."
Run Code Online (Sandbox Code Playgroud)

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