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:
parent
6747dfc803
commit
950eccab4a
|
@ -14,9 +14,9 @@ specific set of instructions. You can learn the basics on the
|
||||||
you’re new to writing `Dockerfile`s, you should start there.
|
you’re 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 you’re creating an Official
|
`Dockerfile`s. We strongly suggest you follow these recommendations (in fact,
|
||||||
Image, you *must* adhere to these practices).
|
if you’re 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:
|
||||||
|
|
||||||
* Don’t do simply `RUN apt-get update` on a single line. This will cause
|
* Don’t 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 there’s 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 there’s 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 what’s in the cache.
|
regardless of what’s 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`, you’ll get dropped into a usable shell, ready to go.
|
`docker run -it python`, you’ll 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 they’ve 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 they’ve 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
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ page_keywords: Docker, docker, registry, accounts, plans, Dockerfile, Docker Hub
|
||||||
|
|
||||||
You’ve been given the job of creating an image for an Official Repository
|
You’ve 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 you’re not
|
our guidelines for getting that task done. Even if you’re 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
|
||||||
|
|
Loading…
Reference in New Issue