Revisions and edits based on feedback.

Docker-DCO-1.1-Signed-off-by: Fred Lifton <fred.lifton@docker.com> (github: fredlf)
This commit is contained in:
Fred Lifton 2014-09-23 18:26:02 -07:00
parent 6747dfc803
commit 950eccab4a
2 changed files with 44 additions and 33 deletions

View File

@ -14,9 +14,9 @@ specific set of instructions. You can learn the basics on the
youre new to writing `Dockerfile`s, you should start there. youre new to writing `Dockerfile`s, you should start there.
This document covers the best practices and methods recommended by Docker, This document covers the best practices and methods recommended by Docker,
Inc., for creating easy-to-use, effective `Dockerfile`s. We strongly suggest Inc. and the Docker Community for creating easy-to-use, effective
you follow these recommendations (in fact, if youre creating an Official `Dockerfile`s. We strongly suggest you follow these recommendations (in fact,
Image, you *must* adhere to these practices). if youre creating an Official Image, you *must* adhere to these practices).
You can see many of these practices and recommendations in action in the [buildpack-deps `Dockerfile`](https://github.com/docker-library/buildpack-deps/blob/master/jessie/Dockerfile). You can see many of these practices and recommendations in action in the [buildpack-deps `Dockerfile`](https://github.com/docker-library/buildpack-deps/blob/master/jessie/Dockerfile).
@ -34,10 +34,11 @@ set-up and configuration.
### Use a [`.dockerignore` file](https://docs.docker.com/reference/builder/#the-dockerignore-file) ### Use a [`.dockerignore` file](https://docs.docker.com/reference/builder/#the-dockerignore-file)
For faster uploading and efficiency, you should make use of a `.dockerignore` For faster uploading and efficiency during `docker build`, you should make use
file to exclude files or directories from the build context. For example, unless of a `.dockerignore` file to exclude files or directories from the build
`.git` is needed by your build process or scripts, you should add it to context and final image. For example, unless`.git` is needed by your build
`.dockerignore`, which can save many megabytes worth of upload time. process or scripts, you should add it to `.dockerignore`, which can save many
megabytes worth of upload time.
### Avoid installing unnecessary packages ### Avoid installing unnecessary packages
@ -95,14 +96,18 @@ backslashes.
Probably the most common use-case for `RUN` is an application of `apt-get`. Probably the most common use-case for `RUN` is an application of `apt-get`.
When using `apt-get`, here a few things to keep in mind: When using `apt-get`, here a few things to keep in mind:
* Dont do simply `RUN apt-get update` on a single line. This will cause * Dont do `RUN apt-get update` on a single line. This will cause
caching issues if the referenced archive gets updated, which will make your caching issues if the referenced archive gets updated, which will make your
subsequent `apt-get install` fail without comment. subsequent `apt-get install` fail without comment.
* For the most part, to keep your code more readable and maintainable, avoid * For the most part, to keep your code more readable and maintainable, avoid
`RUN apt-get install -y package-foo && apt-get install -y package-bar`. `RUN apt-get install -y package-foo && apt-get install -y package-bar`.
* Avoid `RUN apt-get upgrade` or `dist-upgrade`, since many of the “essential” packages from the base images will fail to upgrade inside an unprivileged container. If a base package is out of date, you should contact its maintainers. If you know theres a particular package, `foo`, that needs to be updated, use `apt-get install -y foo` and it will update automatically. * Avoid `RUN apt-get upgrade` or `dist-upgrade`, since many of the “essential”
packages from the base images will fail to upgrade inside an unprivileged
container. If a base package is out of date, you should contact its
maintainers. If you know theres a particular package, `foo`, that needs to be
updated, use `apt-get install -y foo` and it will update automatically.
* Do use `RUN apt-get update && apt-get install -y package-bar package-foo * Do use `RUN apt-get update && apt-get install -y package-bar package-foo
package-baz`. Writing the instruction this way not only makes it easier to read package-baz`. Writing the instruction this way not only makes it easier to read
@ -111,7 +116,7 @@ will naturally be busted and the latest versions will be installed with no
further coding or manual intervention required. further coding or manual intervention required.
* Further natural cache-busting can be realized by version-pinning packages * Further natural cache-busting can be realized by version-pinning packages
(e.g., `package-foo=1.3.*`) since it will force retrieval of that version (e.g., `package-foo=1.3.*`). This will force retrieval of that version
regardless of whats in the cache. regardless of whats in the cache.
Forming your `apt-get` code this way will greatly ease maintenance and reduce Forming your `apt-get` code this way will greatly ease maintenance and reduce
failures due to unanticipated changes in required packages. failures due to unanticipated changes in required packages.
@ -120,8 +125,9 @@ failures due to unanticipated changes in required packages.
Below is a well-formed `RUN` instruction that demonstrates the above Below is a well-formed `RUN` instruction that demonstrates the above
recommendations. Note that the last package, `s3cmd`, specifies a version recommendations. Note that the last package, `s3cmd`, specifies a version
`1.1.0*`, which will bust the `apt-get` cache and force the installation of `1.1.0*`. If the image previously used an older version, specifying the new one
that version (which in this case had a new, required feature). will cause a cache bust of `apt-get update` and ensure the installation of
the new version (which in this case had a new, required feature).
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
aufs-tools \ aufs-tools \
@ -146,14 +152,14 @@ that version (which in this case had a new, required feature).
### [`CMD`](https://docs.docker.com/reference/builder/#cmd) ### [`CMD`](https://docs.docker.com/reference/builder/#cmd)
The `CMD` instruction should be used to run the software contained by your The `CMD` instruction should be used to run the software contained by your
image, along with any arguments. `CMD` should almost always be used in the image, along with any arguments. `CMD` should almost always be used in the
form of `CMD [“executable”, “param1”, “param2”…]`. Thus, if the image is for a form of `CMD [“executable”, “param1”, “param2”…]`. Thus, if the image is for a
service (Apache, Rails, etc.), you would run something like service (Apache, Rails, etc.), you would run something like
`CMD ["apache2","-DFOREGROUND"]`. Indeed, this form of the instruction is `CMD ["apache2","-DFOREGROUND"]`. Indeed, this form of the instruction is
recommended for any service-based image. recommended for any service-based image.
In most other cases, `CMD` should be given an interactive shell (bash, python, In most other cases, `CMD` should be given an interactive shell (bash, python,
perl, etc). For example, `CMD ["perl", "-de0"]`, `CMD ["python"]`, or perl, etc), for example, `CMD ["perl", "-de0"]`, `CMD ["python"]`, or
`CMD [“php”, “-a”]`. Using this form means that when you execute something like `CMD [“php”, “-a”]`. Using this form means that when you execute something like
`docker run -it python`, youll get dropped into a usable shell, ready to go. `docker run -it python`, youll get dropped into a usable shell, ready to go.
`CMD` should rarely be used in the manner of `CMD [“param”, “param”]` in `CMD` should rarely be used in the manner of `CMD [“param”, “param”]` in
@ -163,11 +169,11 @@ works.
### [`EXPOSE`](https://docs.docker.com/reference/builder/#expose) ### [`EXPOSE`](https://docs.docker.com/reference/builder/#expose)
The `EXPOSE` instruction is the way you tell the users of your image where to The `EXPOSE` instruction indicates the ports on which a container will listen
connect. Consequently, you should use the common, traditional port for your for connections. Consequently, you should use the common, traditional port for
application. For example, an image containing the Apache web server would use your application. For example, an image containing the Apache web server would
`EXPOSE 80` while an image containing MongoDB would use `EXPOSE 27017` and so use `EXPOSE 80`, while an image containing MongoDB would use `EXPOSE 27017` and
on. so on.
For external access, your users can execute `docker run` with a flag indicating For external access, your users can execute `docker run` with a flag indicating
how to map the specified port to the port of their choice. how to map the specified port to the port of their choice.
@ -207,9 +213,10 @@ not immediately obvious. Consequently, the best use for `ADD` is local tar file
auto-extraction into the image, as in `ADD rootfs.tar.xz /`. auto-extraction into the image, as in `ADD rootfs.tar.xz /`.
Because image size matters, using `ADD` to fetch packages from remote URLs is Because image size matters, using `ADD` to fetch packages from remote URLs is
strongly discouraged; you should use `curl` or `wget` instead. That way you can, where possible, delete the files you no longer need after theyve been strongly discouraged; you should use `curl` or `wget` instead. That way you can
extracted without having to add another layer in your image. For example, you delete the files you no longer need after theyve been extracted and you won't
should avoid doing things like: have to add another layer in your image. For example, you should avoid doing
things like:
ADD http://example.com/big.tar.xz /usr/src/things/ ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
@ -218,9 +225,9 @@ should avoid doing things like:
And instead, do something like: And instead, do something like:
RUN mdkir -p /usr/src/things \ RUN mdkir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.gz \ && curl -SL http://example.com/big.tar.gz \
| tar -xJC /usr/src/things \ | tar -xJC /usr/src/things \
&& make -C /usr/src/things all && make -C /usr/src/things all
For other items (files, directories) that do not require `ADD`s tar For other items (files, directories) that do not require `ADD`s tar
auto-extraction capability, you should always use `COPY`. auto-extraction capability, you should always use `COPY`.
@ -311,9 +318,9 @@ Images built from `ONBUILD` should get a separate tag, for example:
`ruby:1.9-onbuild` or `ruby:2.0-onbuild`. `ruby:1.9-onbuild` or `ruby:2.0-onbuild`.
Be careful when putting `ADD` or `COPY` in `ONBUILD`. The “onbuild” image will Be careful when putting `ADD` or `COPY` in `ONBUILD`. The “onbuild” image will
fail catastrophically if it is missing the the resource being added. Adding a fail catastrophically if the new build's context is missing the resource being
separate tag, as recommended above, will help mitigate this by allowing the added. Adding a separate tag, as recommended above, will help mitigate this by
`Dockerfile` author to make a choice. allowing the `Dockerfile` author to make a choice.
## Examples For Official Repositories ## Examples For Official Repositories

View File

@ -8,7 +8,7 @@ page_keywords: Docker, docker, registry, accounts, plans, Dockerfile, Docker Hub
Youve been given the job of creating an image for an Official Repository Youve been given the job of creating an image for an Official Repository
hosted on [Docker Hub Registry](https://registry.hub.docker.com/). These are hosted on [Docker Hub Registry](https://registry.hub.docker.com/). These are
Docker, Inc.s guidelines for getting that task done. Even if youre not our guidelines for getting that task done. Even if youre not
planning to create an Official Repo, you can think of these guidelines as best planning to create an Official Repo, you can think of these guidelines as best
practices for image creation generally. practices for image creation generally.
@ -91,11 +91,15 @@ In terms of content, the long description must include the following sections:
* Issues & Contribution Info * Issues & Contribution Info
#### Overview & links #### Overview & links
A section providing (a) an overview of the software contained in the image,
similar to the introduction in a Wikipedia entry and (b) a selection of links
to outside resources that help to describe the software.
This section *must* also include a link to the `Dockerfile`. This section should provide:
* an overview of the software contained in the image, similar to the
introduction in a Wikipedia entry,
* a selection of links to outside resources that help to describe the software,
* a *mandatory* link to the `Dockerfile`.
#### How-to/usage #### How-to/usage
A section that describes how to run and use the image, including common use A section that describes how to run and use the image, including common use