From 0a0037c6fd259f34bef4ed29089d11dd9df7fe4c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 23 Sep 2020 12:42:17 +0200 Subject: [PATCH 1/3] builder: rephrase ENV section, remove examples for ENV key value without '=' The `ENV key value` form can be ambiguous, for example, the following defines a single env-variable (`ONE`) with value `"TWO= THREE=world"`: ENV ONE TWO= THREE=world While we cannot deprecate/remove that syntax (as it would break existing Dockerfiles), we should reduce exposure of the format in our examples. Signed-off-by: Sebastiaan van Stijn --- docs/reference/builder.md | 71 +++++++++++++++------------- docs/reference/commandline/build.md | 2 +- docs/reference/commandline/commit.md | 2 +- docs/reference/commandline/import.md | 2 +- e2e/image/build_test.go | 4 +- man/Dockerfile.5.md | 6 +-- man/src/container/commit.md | 2 +- man/src/image/import.md | 2 +- 8 files changed, 47 insertions(+), 44 deletions(-) diff --git a/docs/reference/builder.md b/docs/reference/builder.md index 0b025f15c6..ab3c9e33d8 100644 --- a/docs/reference/builder.md +++ b/docs/reference/builder.md @@ -500,10 +500,10 @@ Example (parsed representation is displayed after the `#`): ```dockerfile FROM busybox -ENV foo /bar -WORKDIR ${foo} # WORKDIR /bar -ADD . $foo # ADD . /bar -COPY \$foo /quux # COPY $foo /quux +ENV FOO=/bar +WORKDIR ${FOO} # WORKDIR /bar +ADD . $FOO # ADD . /bar +COPY \$FOO /quux # COPY $FOO /quux ``` Environment variables are supported by the following list of instructions in @@ -994,53 +994,56 @@ port. For detailed information, see the ## ENV ```dockerfile -ENV ENV = ... ``` The `ENV` instruction sets the environment variable `` to the value ``. This value will be in the environment for all subsequent instructions in the build stage and can be [replaced inline](#environment-replacement) in -many as well. - -The `ENV` instruction has two forms. The first form, `ENV `, -will set a single variable to a value. The entire string after the first -space will be treated as the `` - including whitespace characters. The -value will be interpreted for other environment variables, so quote characters -will be removed if they are not escaped. - -The second form, `ENV = ...`, allows for multiple variables to -be set at one time. Notice that the second form uses the equals sign (=) -in the syntax, while the first form does not. Like command line parsing, +many as well. The value will be interpreted for other environment variables, so +quote characters will be removed if they are not escaped. Like command line parsing, quotes and backslashes can be used to include spaces within values. -For example: +Example: ```dockerfile -ENV myName="John Doe" myDog=Rex\ The\ Dog \ - myCat=fluffy +ENV MY_NAME="John Doe" +ENV MY_DOG=Rex\ The\ Dog +ENV MY_CAT=fluffy ``` -and +The `ENV` instruction allows for multiple `= ...` variables to be set +at one time, and the example below will yield the same net results in the final +image: ```dockerfile -ENV myName John Doe -ENV myDog Rex The Dog -ENV myCat fluffy +ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \ + MY_CAT=fluffy ``` -will yield the same net results in the final image. - The environment variables set using `ENV` will persist when a container is run from the resulting image. You can view the values using `docker inspect`, and change them using `docker run --env =`. > **Note** > -> Environment persistence can cause unexpected side effects. For example, -> setting `ENV DEBIAN_FRONTEND noninteractive` may confuse apt-get -> users on a Debian-based image. To set a value for a single command, use -> `RUN = `. +> Environment variable persistence can cause unexpected side effects. For example, +> setting `ENV DEBIAN_FRONTEND=noninteractive` changes the behavior of `apt-get`, +> and may confuse users of your image. +> +> If an environment variable is only needed during build, and not in the final +> image, consider setting a value for a single command instead: +> +> ```dockerfile +> RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ... +> ``` +> +> Or using [`ARG`](#arg), which is not persisted in the final image: +> +> ```dockerfile +> ARG DEBIAN_FRONTEND=noninteractive +> RUN apt-get update && apt-get install -y ... +> ``` ## ADD @@ -1768,7 +1771,7 @@ The `WORKDIR` instruction can resolve environment variables previously set using For example: ```dockerfile -ENV DIRPATH /path +ENV DIRPATH=/path WORKDIR $DIRPATH/$DIRNAME RUN pwd ``` @@ -1873,7 +1876,7 @@ this Dockerfile with an `ENV` and `ARG` instruction. ```dockerfile FROM ubuntu ARG CONT_IMG_VER -ENV CONT_IMG_VER v1.0.0 +ENV CONT_IMG_VER=v1.0.0 RUN echo $CONT_IMG_VER ``` @@ -1894,7 +1897,7 @@ useful interactions between `ARG` and `ENV` instructions: ```dockerfile FROM ubuntu ARG CONT_IMG_VER -ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0} +ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0} RUN echo $CONT_IMG_VER ``` @@ -2030,7 +2033,7 @@ Consider another example under the same command line: ```dockerfile FROM ubuntu ARG CONT_IMG_VER -ENV CONT_IMG_VER $CONT_IMG_VER +ENV CONT_IMG_VER=$CONT_IMG_VER RUN echo $CONT_IMG_VER ``` @@ -2045,7 +2048,7 @@ this Dockerfile: ```dockerfile FROM ubuntu ARG CONT_IMG_VER -ENV CONT_IMG_VER hello +ENV CONT_IMG_VER=hello RUN echo $CONT_IMG_VER ``` diff --git a/docs/reference/commandline/build.md b/docs/reference/commandline/build.md index 3b53da0adf..3117eb3e9d 100644 --- a/docs/reference/commandline/build.md +++ b/docs/reference/commandline/build.md @@ -742,7 +742,7 @@ FROM busybox RUN echo hello > /hello RUN echo world >> /hello RUN touch remove_me /remove_me -ENV HELLO world +ENV HELLO=world RUN rm /remove_me ``` diff --git a/docs/reference/commandline/commit.md b/docs/reference/commandline/commit.md index 2244df6e2a..4af081440b 100644 --- a/docs/reference/commandline/commit.md +++ b/docs/reference/commandline/commit.md @@ -73,7 +73,7 @@ $ docker inspect -f "{{ .Config.Env }}" c3f279d17e0a [HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin] -$ docker commit --change "ENV DEBUG true" c3f279d17e0a svendowideit/testimage:version3 +$ docker commit --change "ENV DEBUG=true" c3f279d17e0a svendowideit/testimage:version3 f5283438590d diff --git a/docs/reference/commandline/import.md b/docs/reference/commandline/import.md index 686776ccb2..497f1aa8c2 100644 --- a/docs/reference/commandline/import.md +++ b/docs/reference/commandline/import.md @@ -72,7 +72,7 @@ $ sudo tar -c . | docker import - exampleimagedir ### Import from a local directory with new configurations ```bash -$ sudo tar -c . | docker import --change "ENV DEBUG true" - exampleimagedir +$ sudo tar -c . | docker import --change "ENV DEBUG=true" - exampleimagedir ``` Note the `sudo` in this example – you must preserve diff --git a/e2e/image/build_test.go b/e2e/image/build_test.go index 120fa37f2e..c92c0b0d89 100644 --- a/e2e/image/build_test.go +++ b/e2e/image/build_test.go @@ -116,8 +116,8 @@ func TestBuildIidFileSquash(t *testing.T) { buildDir := fs.NewDir(t, "test-iidfile-squash-build", fs.WithFile("Dockerfile", fmt.Sprintf(` FROM %s - ENV FOO FOO - ENV BAR BAR + ENV FOO=FOO + ENV BAR=BAR RUN touch /fiip RUN touch /foop`, fixtures.AlpineImage)), ) diff --git a/man/Dockerfile.5.md b/man/Dockerfile.5.md index 5191b1930a..46794db87c 100644 --- a/man/Dockerfile.5.md +++ b/man/Dockerfile.5.md @@ -201,7 +201,7 @@ A Dockerfile is similar to a Makefile. from the resulting image. Use `docker inspect` to inspect these values, and change them using `docker run --env =`. - Note that setting "`ENV DEBIAN_FRONTEND noninteractive`" may cause + Note that setting "`ENV DEBIAN_FRONTEND=noninteractive`" may cause unintended consequences, because it will persist when the container is run interactively, as with the following command: `docker run -t -i image bash` @@ -388,7 +388,7 @@ A Dockerfile is similar to a Makefile. ``` 1 FROM ubuntu 2 ARG CONT_IMG_VER - 3 ENV CONT_IMG_VER v1.0.0 + 3 ENV CONT_IMG_VER=v1.0.0 4 RUN echo $CONT_IMG_VER ``` Then, assume this image is built with this command: @@ -408,7 +408,7 @@ A Dockerfile is similar to a Makefile. ``` 1 FROM ubuntu 2 ARG CONT_IMG_VER - 3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0} + 3 ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0} 4 RUN echo $CONT_IMG_VER ``` diff --git a/man/src/container/commit.md b/man/src/container/commit.md index 43d2e9c25d..6b7b9d1af5 100644 --- a/man/src/container/commit.md +++ b/man/src/container/commit.md @@ -27,4 +27,4 @@ variable set to "true", you can create a new image based on that container by first getting the container's ID with `docker ps` and then running: - $ docker container commit -c="ENV DEBUG true" 98bd7fc99854 debug-image + $ docker container commit -c="ENV DEBUG=true" 98bd7fc99854 debug-image diff --git a/man/src/image/import.md b/man/src/image/import.md index 1f18185cec..2756c368f4 100644 --- a/man/src/image/import.md +++ b/man/src/image/import.md @@ -36,7 +36,7 @@ Import to docker via pipe and stdin: ## Apply specified Dockerfile instructions while importing the image This example sets the docker image ENV variable DEBUG to true by default. - # tar -c . | docker image import -c="ENV DEBUG true" - exampleimagedir + # tar -c . | docker image import -c="ENV DEBUG=true" - exampleimagedir ## When the daemon supports multiple operating systems If the daemon supports multiple operating systems, and the image being imported From a4a3d2f94dae8fe7db6ae9be6574087841a68fd9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 23 Sep 2020 13:05:00 +0200 Subject: [PATCH 2/3] builder: add note about alternative syntax Signed-off-by: Sebastiaan van Stijn --- docs/reference/builder.md | 40 ++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/docs/reference/builder.md b/docs/reference/builder.md index ab3c9e33d8..bbaa010bbc 100644 --- a/docs/reference/builder.md +++ b/docs/reference/builder.md @@ -1025,25 +1025,43 @@ The environment variables set using `ENV` will persist when a container is run from the resulting image. You can view the values using `docker inspect`, and change them using `docker run --env =`. -> **Note** +Environment variable persistence can cause unexpected side effects. For example, +setting `ENV DEBIAN_FRONTEND=noninteractive` changes the behavior of `apt-get`, +and may confuse users of your image. + +If an environment variable is only needed during build, and not in the final +image, consider setting a value for a single command instead: + +```dockerfile +RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ... +``` + +Or using [`ARG`](#arg), which is not persisted in the final image: + +```dockerfile +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y ... +``` + +> **Alternative syntax** > -> Environment variable persistence can cause unexpected side effects. For example, -> setting `ENV DEBIAN_FRONTEND=noninteractive` changes the behavior of `apt-get`, -> and may confuse users of your image. -> -> If an environment variable is only needed during build, and not in the final -> image, consider setting a value for a single command instead: +> The `ENV` instruction also allows an alternative syntax `ENV `, +> omitting the `=`. For example: > > ```dockerfile -> RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ... +> ENV MY_VAR my-value > ``` > -> Or using [`ARG`](#arg), which is not persisted in the final image: +> This syntax does not allow for multiple environment-variables to be set in a +> single `ENV` instruction, and can be confusing. For example, the following +> sets a single environment variable (`ONE`) with value `"TWO= THREE=world"`: > > ```dockerfile -> ARG DEBIAN_FRONTEND=noninteractive -> RUN apt-get update && apt-get install -y ... +> ENV ONE TWO= THREE=world > ``` +> +> The alternative syntax is supported for backward compatibility, but discouraged +> for the reasons outlined above, and may be removed in a future release. ## ADD From 0eb3cfd261d7fe6fe22a0d8d2768a5270c226604 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 23 Sep 2020 13:23:59 +0200 Subject: [PATCH 3/3] Add test-case for env with, and without = Signed-off-by: Sebastiaan van Stijn --- cli/command/image/import_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cli/command/image/import_test.go b/cli/command/image/import_test.go index 94e7d723aa..f2664f1275 100644 --- a/cli/command/image/import_test.go +++ b/cli/command/image/import_test.go @@ -81,6 +81,14 @@ func TestNewImportCommandSuccess(t *testing.T) { }, { name: "change", + args: []string{"--change", "ENV DEBUG=true", "-"}, + imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) { + assert.Check(t, is.Equal("ENV DEBUG=true", options.Changes[0])) + return ioutil.NopCloser(strings.NewReader("")), nil + }, + }, + { + name: "change legacy syntax", args: []string{"--change", "ENV DEBUG true", "-"}, imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) { assert.Check(t, is.Equal("ENV DEBUG true", options.Changes[0]))