Dockerfile: Setting multiple environment variables in single line

DockerDockerfile

Docker Problem Overview


I was under the impression that environmental variables could be set on a single line as follows so as to minimize intermediary images.

FROM alpine:3.6
ENV RUBY_MAJOR 2.4 \
    RUBY_VERSION 2.4.1 \
    RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \
    RUBYGEMS_VERSION 2.6.12 \
    BUNDLER_VERSION 1.15.3

However, running a container based off of this snippet and calling # set |grep RU I see that the variables are not being assigned separately, but are combined into a single string.

RUBY_MAJOR='2.4     RUBY_VERSION 2.4.1     RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654     RUBYGEMS_VERSION 2.6.12     BUNDLER_VERSION 1.15.3'

However, if I explicitly set each variable as below, I get the expected output and there are no errors when calling the variables.

ENV RUBY_MAJOR 2.4
ENV RUBY_VERSION 2.4.1
ENV RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654
ENV RUBYGEMS_VERSION 2.6.12
ENV BUNDLER_VERSION 1.15.3

Question: Is it is possible to combine the setting of environment variables on a single line? If so, how would I do it? And is it a good practice?

Docker Solutions


Solution 1 - Docker

There are two formats for specifying environments. If you need single variable then you below format

ENV X Y

This will assign X as Y

ENV X Y Z

This will assign X as Y Z

If you need to assign multiple environment variables then you use the other format

ENV X=Y Z=A

This will assign X as Y and Z as A. So your Dockerfile should be

FROM alpine:3.6
ENV RUBY_MAJOR=2.4 \
    RUBY_VERSION=2.4.1 \
    RUBY_DOWNLOAD_SHA256=4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \
    RUBYGEMS_VERSION=2.6.12 \
    BUNDLER_VERSION=1.15.3

RUN env

Solution 2 - Docker

You do not need to worry about many ENV commands each creating a new intermediate layer for your final image created by your Dockerfile.

from Best practices for writing Dockerfiles

> ### Minimize the number of layers > > Prior to Docker 17.05, and even more, prior to Docker 1.10, it was important to minimize the number of layers in your image. The following improvements have mitigated this need: > > * In Docker 1.10 and higher, only RUN, COPY, and ADD instructions create layers. Other instructions create temporary intermediate images, and no longer directly increase the size of the build. > > * Docker 17.05 and higher add support for multi-stage builds, which allow you to copy only the artifacts you need into the final image. This allows you to include tools and debug information in your intermediate build stages without increasing the size of the final image.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrianWilsonView Question on Stackoverflow
Solution 1 - DockerTarun LalwaniView Answer on Stackoverflow
Solution 2 - DockerMike LippertView Answer on Stackoverflow