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.
This document covers the best practices and methods recommended by Docker,
Inc., for creating easy-to-use, effective `Dockerfile`s. We strongly suggest
you follow these recommendations (in fact, if youre creating an Official
Image, you *must* adhere to these practices).
Inc. and the Docker Community for creating easy-to-use, effective
`Dockerfile`s. We strongly suggest you follow these recommendations (in fact,
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).
@ -34,10 +34,11 @@ set-up and configuration.
### 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`
file to exclude files or directories from the build context. For example, unless
`.git` is needed by your build process or scripts, you should add it to
`.dockerignore`, which can save many megabytes worth of upload time.
For faster uploading and efficiency during `docker build`, you should make use
of a `.dockerignore` file to exclude files or directories from the build
context and final image. For example, unless`.git` is needed by your build
process or scripts, you should add it to `.dockerignore`, which can save many
megabytes worth of upload time.
### Avoid installing unnecessary packages
@ -95,14 +96,18 @@ backslashes.
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:
* 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
subsequent `apt-get install` fail without comment.
* 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`.
* 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
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 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.
Forming your `apt-get` code this way will greatly ease maintenance and reduce
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
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
that version (which in this case had a new, required feature).
`1.1.0*`. If the image previously used an older version, specifying the new one
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 \
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)
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
service (Apache, Rails, etc.), you would run something like
`CMD ["apache2","-DFOREGROUND"]`. Indeed, this form of the instruction is
recommended for any service-based image.
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
`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
@ -163,11 +169,11 @@ works.
### [`EXPOSE`](https://docs.docker.com/reference/builder/#expose)
The `EXPOSE` instruction is the way you tell the users of your image where to
connect. Consequently, you should use the common, traditional port for your
application. For example, an image containing the Apache web server would use
`EXPOSE 80` while an image containing MongoDB would use `EXPOSE 27017` and so
on.
The `EXPOSE` instruction indicates the ports on which a container will listen
for connections. Consequently, you should use the common, traditional port for
your application. For example, an image containing the Apache web server would
use `EXPOSE 80`, while an image containing MongoDB would use `EXPOSE 27017` and
so on.
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.
@ -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 /`.
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
extracted without having to add another layer in your image. For example, you
should avoid doing things like:
strongly discouraged; you should use `curl` or `wget` instead. That way you can
delete the files you no longer need after theyve been extracted and you won't
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/
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:
RUN mdkir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.gz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
&& curl -SL http://example.com/big.tar.gz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
For other items (files, directories) that do not require `ADD`s tar
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`.
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
separate tag, as recommended above, will help mitigate this by allowing the
`Dockerfile` author to make a choice.
fail catastrophically if the new build's context is missing the resource being
added. Adding a separate tag, as recommended above, will help mitigate this by
allowing the `Dockerfile` author to make a choice.
## 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
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
practices for image creation generally.
@ -91,11 +91,15 @@ In terms of content, the long description must include the following sections:
* Issues & Contribution Info
#### 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
A section that describes how to run and use the image, including common use