diff --git a/docs/reference/builder.md b/docs/reference/builder.md index 537cc98ece..848d69717c 100644 --- a/docs/reference/builder.md +++ b/docs/reference/builder.md @@ -966,6 +966,127 @@ For example: The output of the final `pwd` command in this `Dockerfile` would be `/path/$DIRNAME` +## ARG + + ARG [=] + +The `ARG` instruction defines a variable that users can pass at build-time to +the builder with the `docker build` command using the `--build-arg +=` flag. If a user specifies a build argument that was not +defined in the Dockerfile, the build outputs an error. + +``` +One or more build-args were not consumed, failing build. +``` + +The Dockerfile author can define a single variable by specifying `ARG` once or many +variables by specifying `ARG` more than once. For example, a valid Dockerfile: + +``` +FROM busybox +ARG user1 +ARG buildno +... +``` + +A Dockerfile author may optionally specify a default value for an `ARG` instruction: + +``` +FROM busybox +ARG user1=someuser +ARG buildno=1 +... +``` + +If an `ARG` value has a default and if there is no value passed at build-time, the +builder uses the default. + +An `ARG` variable definition comes into effect from the line on which it is +defined in the `Dockerfile` not from the argument's use on the command-line or +elsewhere. For example, consider this Dockerfile: + +``` +1 FROM busybox +2 USER ${user:-some_user} +3 ARG user +4 USER $user +... +``` +A user builds this file by calling: + +``` +$ docker build --build-arg user=what_user Dockerfile +``` + +The `USER` at line 2 evaluates to `some_user` as the `user` variable is defined on the +subsequent line 3. The `USER` at line 4 evaluates to `what_user` as `user` is +defined and the `what_user` value was passed on the command line. Prior to its definition by an +`ARG` instruction, any use of a variable results in an empty string. + +> **Note:** It is not recommended to use build-time variables for +> passing secrets like github keys, user credentials etc. + +You can use an `ARG` or an `ENV` instruction to specify variables that are +available to the `RUN` instruction. Environment variables defined using the +`ENV` instruction always override an `ARG` instruction of the same name. Consider +this Dockerfile with an `ENV` and `ARG` instruction. + +``` +1 FROM ubuntu +2 ARG CONT_IMG_VER +3 ENV CONT_IMG_VER v1.0.0 +4 RUN echo $CONT_IMG_VER +``` +Then, assume this image is built with this command: + +``` +$ docker build --build-arg CONT_IMG_VER=v2.0.1 Dockerfile +``` + +In this case, the `RUN` instruction uses `v1.0.0` instead of the `ARG` setting +passed by the user:`v2.0.1` This behavior is similar to a shell +script where a locally scoped variable overrides the variables passed as +arguments or inherited from environment, from its point of definition. + +Using the example above but a different `ENV` specification you can create more +useful interactions between `ARG` and `ENV` instructions: + +``` +1 FROM ubuntu +2 ARG CONT_IMG_VER +3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0} +4 RUN echo $CONT_IMG_VER +``` + +The command line passes the `--build-arg` and sets the `v2.0.1` value. And the `ARG +CONT_IMG_VER` is defined on line 2 of the Dockerfile. On line 3, the `ENV` +instruction of the same name resolves to `v2.0.1` as the build-time variable +was passed from the command line and expanded here. + +The variable expansion technique in this example allows you to pass arguments +from the command line and persist them in the final image by leveraging the `ENV` +instruction. Variable expansion is only supported for the `Dockerfile` instructions +described [here](#environment-replacement). + +Unlike an `ARG` instruction, `ENV` values are always persisted in the built image. If +`docker build` were run without setting the `--build-arg` flag, then +`CONT_IMG_VER` is still persisted in the image but its value would be `v1.0.0`. + +Docker has a set of predefined `ARG` variables that you can use without a +corresponding `ARG` instruction in the Dockerfile. + +* `HTTP_PROXY` +* `http_proxy` +* `HTTPS_PROXY` +* `https_proxy` +* `FTP_PROXY` +* `ftp_proxy` +* `NO_PROXY` +* `no_proxy` + +To use these, simply pass them on the command line using the `--build-arg +=` flag. + ## ONBUILD ONBUILD [INSTRUCTION] diff --git a/docs/reference/commandline/build.md b/docs/reference/commandline/build.md index 633d1132de..8cb6b13107 100644 --- a/docs/reference/commandline/build.md +++ b/docs/reference/commandline/build.md @@ -17,6 +17,7 @@ weight=1 -f, --file="" Name of the Dockerfile (Default is 'PATH/Dockerfile') --force-rm=false Always remove intermediate containers + --build-arg=[] Set build-time variables --no-cache=false Do not use cache when building the image --pull=false Always attempt to pull a newer version of the image -q, --quiet=false Suppress the verbose output generated by the containers @@ -251,3 +252,22 @@ flag](/reference/run/#specifying-custom-cgroups). Using the `--ulimit` option with `docker build` will cause each build step's container to be started using those [`--ulimit` flag values](/reference/run/#setting-ulimits-in-a-container). + +You can use `ENV` instructions in a Dockerfile to define variable +values. These values persist in the built image. However, often +persistence is not what you want. Users want to specify variables differently +depending on which host they build an image on. + +A good example is `http_proxy` or source versions for pulling intermediate +files. The `ARG` instruction lets Dockerfile authors define values that users +can set at build-time using the `---build-arg` flag: + + $ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 . + +This flag allows you to pass the build-time variables that are +accessed like regular environment variables in the `RUN` instruction of the +Dockerfile. Also, these values don't persist in the intermediate or final images +like `ENV` values do. + +For detailed information on using `ARG` and `ENV` instructions, see the +[Dockerfile reference](/reference/builder). diff --git a/man/Dockerfile.5.md b/man/Dockerfile.5.md index 0b188ac330..b29745e2e7 100644 --- a/man/Dockerfile.5.md +++ b/man/Dockerfile.5.md @@ -317,6 +317,126 @@ A Dockerfile is similar to a Makefile. In the above example, the output of the **pwd** command is **a/b/c**. +**ARG** + -- ARG [=] + + The `ARG` instruction defines a variable that users can pass at build-time to + the builder with the `docker build` command using the `--build-arg + =` flag. If a user specifies a build argument that was not + defined in the Dockerfile, the build outputs an error. + + ``` + One or more build-args were not consumed, failing build. + ``` + + The Dockerfile author can define a single variable by specifying `ARG` once or many + variables by specifying `ARG` more than once. For example, a valid Dockerfile: + + ``` + FROM busybox + ARG user1 + ARG buildno + ... + ``` + + A Dockerfile author may optionally specify a default value for an `ARG` instruction: + + ``` + FROM busybox + ARG user1=someuser + ARG buildno=1 + ... + ``` + + If an `ARG` value has a default and if there is no value passed at build-time, the + builder uses the default. + + An `ARG` variable definition comes into effect from the line on which it is + defined in the `Dockerfile` not from the argument's use on the command-line or + elsewhere. For example, consider this Dockerfile: + + ``` + 1 FROM busybox + 2 USER ${user:-some_user} + 3 ARG user + 4 USER $user + ... + ``` + A user builds this file by calling: + + ``` + $ docker build --build-arg user=what_user Dockerfile + ``` + + The `USER` at line 2 evaluates to `some_user` as the `user` variable is defined on the + subsequent line 3. The `USER` at line 4 evaluates to `what_user` as `user` is + defined and the `what_user` value was passed on the command line. Prior to its definition by an + `ARG` instruction, any use of a variable results in an empty string. + + > **Note:** It is not recommended to use build-time variables for + > passing secrets like github keys, user credentials etc. + + You can use an `ARG` or an `ENV` instruction to specify variables that are + available to the `RUN` instruction. Environment variables defined using the + `ENV` instruction always override an `ARG` instruction of the same name. Consider + this Dockerfile with an `ENV` and `ARG` instruction. + + ``` + 1 FROM ubuntu + 2 ARG CONT_IMG_VER + 3 ENV CONT_IMG_VER v1.0.0 + 4 RUN echo $CONT_IMG_VER + ``` + Then, assume this image is built with this command: + + ``` + $ docker build --build-arg CONT_IMG_VER=v2.0.1 Dockerfile + ``` + + In this case, the `RUN` instruction uses `v1.0.0` instead of the `ARG` setting + passed by the user:`v2.0.1` This behavior is similar to a shell + script where a locally scoped variable overrides the variables passed as + arguments or inherited from environment, from its point of definition. + + Using the example above but a different `ENV` specification you can create more + useful interactions between `ARG` and `ENV` instructions: + + ``` + 1 FROM ubuntu + 2 ARG CONT_IMG_VER + 3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0} + 4 RUN echo $CONT_IMG_VER + ``` + + The command line passes the `--build-arg` and sets the `v2.0.1` value. And the `ARG + CONT_IMG_VER` is defined on line 2 of the Dockerfile. On line 3, the `ENV` + instruction of the same name resolves to `v2.0.1` as the build-time variable + was passed from the command line and expanded here. + + The variable expansion technique in this example allows you to pass arguments + from the command line and persist them in the final image by leveraging the `ENV` + instruction. Variable expansion is only supported for the `Dockerfile` instructions + described [here](#environment-replacement). + + Unlike an `ARG` instruction, `ENV` values are always persisted in the built image. If + `docker build` were run without setting the `--build-arg` flag, then + `CONT_IMG_VER` is still persisted in the image but its value would be `v1.0.0`. + + Docker has a set of predefined `ARG` variables that you can use without a + corresponding `ARG` instruction in the Dockerfile. + + * `HTTP_PROXY` + * `http_proxy` + * `HTTPS_PROXY` + * `https_proxy` + * `FTP_PROXY` + * `ftp_proxy` + * `NO_PROXY` + * `no_proxy` + + To use these, simply pass them on the command line using the `--build-arg + =` flag. + **ONBUILD** -- `ONBUILD [INSTRUCTION]` The **ONBUILD** instruction adds a trigger instruction to an image. The diff --git a/man/docker-build.1.md b/man/docker-build.1.md index a8714b775a..f725f83aa8 100644 --- a/man/docker-build.1.md +++ b/man/docker-build.1.md @@ -8,6 +8,7 @@ docker-build - Build a new image from the source code at PATH **docker build** [**--help**] [**-f**|**--file**[=*PATH/Dockerfile*]] +[**--build-arg**[=*[]*]] [**--force-rm**[=*false*]] [**--no-cache**[=*false*]] [**--pull**[=*false*]] @@ -51,6 +52,24 @@ cloned locally and then sent as the context. the remote context. In all cases, the file must be within the build context. The default is *Dockerfile*. +**--build-arg**=*variable* + Set value for build-time variable. This option allows you to specify +values of the variables that are available for expansion/substitution in the +Dockerfile instructions like ADD, COPY etc, without an explicit prior definition by +the ENV instruction. The build-time variables are also passed as environment +context for the command(s) that will be executed as part of RUN instruction +of Dockerfile, if there is no explicit prior definition by the ENV instruction. +Normally, these variables are not persisted in the resulting Docker image. This gives +the flexibility to build an image by passing host specific environment variables (like +http_proxy) that will be used on the RUN commands without affecting portability +of the generated image. +However, as with any variable, they can be persisted in the final image if they are used in an +ENV instruction (e.g. ENV myName=$myName will save myName in the image). + +Only the build-time variables that are defined using the ARG instruction of Dockerfile +are allowed to be expanded or passed as environment to the RUN command. Read more about +ARG instruction in Dockerfile reference. + **--force-rm**=*true*|*false* Always remove intermediate containers, even after unsuccessful builds. The default is *false*.