Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default value with shell expressions in Dockerfile ARG and ENV

I'd like to receive the version number as a single argument and extract major/minor numbers for various places in URLs at the RUN scripts in a Dockerfile.

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}...

If I try the above, the shell expressions are not evaluated and just pasted as-is in the later RUN scripts.

Would be there better way to achieve this, without creating an external shell scripts that wraps this Dockerfile?

like image 918
Achimnol Avatar asked Sep 04 '17 07:09

Achimnol


1 Answers

From the documentation:

The ${variable_name} syntax also supports a few of the standard bash modifiers as specified below:

${variable:-word} indicates that if variable is set then the result will be that value. If variable is not set then word will be the result.

${variable:+word} indicates that if variable is set then word will be the result, otherwise the result is the empty string.

ENV is special docker build command and doesn't support this. What you are looking for is to run Shell commands in ENV. So this won't work.

Possible solution is to use a bash script

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"

And change your dockerfile to

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}..."

You can remove the default values from your shell file as they will always be there from the Dockerfile arguments/environment

like image 170
Tarun Lalwani Avatar answered Oct 05 '22 00:10

Tarun Lalwani