Merge pull request #8222 from fredlf/adding_official-repo-guidelines

Edits and fixes based on review.
This commit is contained in:
James Turnbull 2014-10-03 22:03:05 -04:00
commit 95e169a6a1
3 changed files with 105 additions and 64 deletions

View file

@ -2,7 +2,7 @@ page_title: Best Practices for Writing Dockerfiles
page_description: Hints, tips and guidelines for writing clean, reliable Dockerfiles
page_keywords: Examples, Usage, base image, docker, documentation, dockerfile, best practices, hub, official repo
# Best Practices for Writing `Dockerfile`s
# Best practices for writing Dockerfiles
## Overview
@ -14,7 +14,7 @@ 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. and the Docker Community for creating easy-to-use, effective
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).
@ -23,26 +23,27 @@ You can see many of these practices and recommendations in action in the [buildp
> Note: for more detailed explanations of any of the Dockerfile commands
>mentioned here, visit the [Dockerfile Reference](https://docs.docker.com/reference/builder/) page.
## General Guidelines and Recommendations
## General guidelines and recommendations
### Containers should be ephemeral
The container produced by the image your `Dockerfile` defines should be as
ephemeral as possible. “Ephemeral” here means that it can be stopped and
ephemeral as possible. By “ephemeral,” we mean that it can be stopped and
destroyed and a new one built and put in place with an absolute minimum of
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 during `docker build`, you should make use
of a `.dockerignore` file to exclude files or directories from the build
For faster uploading and efficiency during `docker build`, you should use
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
You should avoid installing extra or unnecessary packages just because they
In order to reduce complexity, dependencies, file sizes, and build times, you
should avoid installing extra or unnecessary packages just because they
might be “nice to have.” For example, you dont need to include a text editor
in a database image.
@ -75,7 +76,7 @@ Heres an example from the [`buildpack-deps` image](https://github.com/docker-
mercurial \
subversion
### Build Cache
### Build cache
During the process of building an image Docker will step through the
instructions in your `Dockerfile` executing each in the order specified.
@ -112,42 +113,48 @@ the command string itself will be used to find a match.
Once the cache is invalidated, all subsequent `Dockerfile` commands will
generate new images and the cache will not be used.
## The `Dockerfile` instructions
bzr \
cvs \
git \
mercurial \
subversion
This section contains specific recommendations for the correct usage of the
various instructions contained in a `Dockerfile`.
## The Dockerfile instructions
Below you'll find recommendations for the best way to write the
various instructions available for use in a `Dockerfile`.
### [`FROM`](https://docs.docker.com/reference/builder/#from)
Whenever possible, use Official Repositories as the basis for your image. We
recommend the [Debian image](https://registry.hub.docker.com/_/debian/) since
its very tightly controlled and kept extremely minimal (currently under 100
mb), while still being a full distribution.
Whenever possible, use current Official Repositories as the basis for your
image. We recommend the [Debian image](https://registry.hub.docker.com/_/debian/)
since its very tightly controlled and kept extremely minimal (currently under
100 mb), while still being a full distribution.
### [`RUN`](https://docs.docker.com/reference/builder/#run)
As always, to make your `Dockerfile` more readable, understandable, and
maintainable, put long or complex `RUN` statements on multiple lines separated with
backslashes.
maintainable, put long or complex `RUN` statements on multiple lines separated
with 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:
When using `apt-get`, here are a few things to keep in mind:
* 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.
* 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
* Do write instructions like:
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
and maintain, but also, by including `apt-get update`, ensures that the cache
will naturally be busted and the latest versions will be installed with no
further coding or manual intervention required.
@ -155,7 +162,7 @@ further coding or manual intervention required.
* Further natural cache-busting can be realized by version-pinning packages
(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
Writing your `apt-get` code this way will greatly ease maintenance and reduce
failures due to unanticipated changes in required packages.
#### Example
@ -186,6 +193,11 @@ the new version (which in this case had a new, required feature).
ruby1.9.1-dev \
s3cmd=1.1.0*
Writing the instruction this way also helps you avoid potential duplication of
a given package because it is much easier to read than an instruction like:
RUN apt-get install -y package-foo && apt-get install -y package-bar
### [`CMD`](https://docs.docker.com/reference/builder/#cmd)
The `CMD` instruction should be used to run the software contained by your
@ -273,9 +285,18 @@ auto-extraction capability, you should always use `COPY`.
The best use for `ENTRYPOINT` is as a helper script. Using `ENTRYPOINT` for
other tasks can make your code harder to understand. For example,
`docker run -it official-image bash` is much easier to understand than
`docker run -it --entrypoint bash official-image -i`, especially for Docker
beginners.
....docker run -it official-image bash
is much easier to understand than
....docker run -it --entrypoint bash official-image -i
This is especially true for new Docker users, who might naturally assume the
above command will work fine. In cases where an image uses `ENTRYPOINT` for
anything other than just a wrapper script, the command will fail and the
beginning user will then be forced to learn about `ENTRYPOINT` and
`--entrypoint`.
In order to avoid a situation where commands are run without clear visibility
to the user, make sure your script ends with something like `exec "$@"`. After
@ -305,8 +326,8 @@ fi
exec "$@"
```
That script then gets copied into the container and the run via `ENTRYPOINT` on
container startup:
That script then gets copied into the container and run via `ENTRYPOINT` on
container startup:
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
@ -324,9 +345,9 @@ If a service can run without privileges, use `USER` to change to a non-root
user. Start by creating the user and group in the `Dockerfile` with something
like `RUN groupadd -r postgres && useradd -r -g postgres postgres`.
>**Note** that users/groups in an image get assigned a non-deterministic
>UID/GID in that the “next” UID/GID gets assigned regardless of image
>rebuilds. So, if its critical, you should assign an explicit UID/GID.
> **Note:** Users and groups in an image get a non-deterministic
> UID/GID in that the “next” UID/GID gets assigned regardless of image
> rebuilds. So, if its critical, you should assign an explicit UID/GID.
You should avoid installing or using `sudo` since it has unpredictable TTY and
signal-forwarding behavior that can cause more more problems than it solves. If
@ -334,7 +355,7 @@ you absolutely need functionality similar to `sudo` (e.g., initializing the
daemon as root but running it as non-root), you may be able to use
[“gosu”](https://github.com/tianon/gosu).
Lastly, to reduce layers and complexity, try to minimize switching `USER` back
Lastly, to reduce layers and complexity, avoid switching `USER` back
and forth frequently.
### [`WORKDIR`](https://docs.docker.com/reference/builder/#workdir)

View file

@ -14,7 +14,8 @@ practices for image creation generally.
This document consists of two major sections:
* A list of expected files, resources and supporting items for your image
* A list of expected files, resources and supporting items for your image,
along with best practices for creating those items
* Examples embodying those practices
## Expected Files & Resources
@ -30,7 +31,7 @@ If the repo is private or has otherwise limited access, you must provide a
means of at least “read-only” access for both general users and for the
docker-library maintainers, who need access for review and building purposes.
### A `Dockerfile`
### A Dockerfile
Complete information on `Dockerfile`s can be found in the [Reference section](https://docs.docker.com/reference/builder/).
We also have a page discussing [best practices for writing `Dockerfile`s](/articles/dockerfile_best-practices).
@ -38,9 +39,9 @@ Your `Dockerfile` should adhere to the following:
* It must be written either by using `FROM scratch` or be based on another,
established Official Image.
* It must follow `Dockerfile` best practices. These are discussed in the
[Best Practices document](/articles/dockerfile_best-practices). In addition,
Docker engineer Michael Crosby has a good discussion of Dockerfiles in
* It must follow `Dockerfile` best practices. These are discussed on the
[best practices page](/articles/dockerfile_best-practices). In addition,
Docker engineer Michael Crosby has some good tips for `Dockerfiles` in
this [blog post](http://crosbymichael.com/dockerfile-best-practices-take-2.html).
While [`ONBUILD` triggers](https://docs.docker.com/reference/builder/#onbuild)
@ -49,7 +50,7 @@ are not required, if you choose to use them you should:
* Build both `ONBUILD` and non-`ONBUILD` images, with the `ONBUILD` image
built `FROM` the non-`ONBUILD` image.
* The `ONBUILD` image should be specifically tagged, for example, `ruby:
latest`and `ruby:onbuild`, or `ruby:2` and `ruby:2-onbuild`.
latest`and `ruby:onbuild`, or `ruby:2` and `ruby:2-onbuild`
### A short description
@ -59,7 +60,7 @@ should also:
* Be named `README-short.txt`
* Reside in the repo for the “latest” tag
* Not exceed 200 characters.
* Not exceed 200 characters
### A logo
@ -69,52 +70,54 @@ file should have the following characteristics:
* Be named `logo.png`
* Should reside in the repo for the “latest” tag
* Should be 200px min. in one dimension, 200px max. in the other.
* Should fit inside a 200px square, maximized in one dimension (preferably the
width)
* Square or wide (landscape) is preferred over tall (portrait), but exceptions
can be made based on the logo needed.
can be made based on the logo needed
### A long description
Include a comprehensive description of your image (in markdown format). Only
one description is required; you dont need additional descriptions for each
tag. The file should also:
Include a comprehensive description of your image (in Markdown format, GitHub
flavor preferred). Only one description is required; you dont need additional
descriptions for each tag. The file should also:
* Be named `README.md`
* Reside in the repo for the “latest” tag
* Be no longer than absolutely necessary, while still addressing all the
content requirements.
content requirements
In terms of content, the long description must include the following sections:
* Overview & Links
* How-to/Usage
* Issues & Contribution Info
* Overview & links
* How-to/usage
* Issues & contributions
#### Overview & links
This section should provide:
* an overview of the software contained in the image, similar to the
introduction in a Wikipedia entry,
introduction in a Wikipedia entry
* a selection of links to outside resources that help to describe the software,
* a selection of links to outside resources that help to describe the software
* a *mandatory* link to the `Dockerfile`.
* a *mandatory* link to the `Dockerfile`
#### How-to/usage
A section that describes how to run and use the image, including common use
cases and example `Dockerfile`s (if applicable). Try to provide clear,step-by-
cases and example `Dockerfile`s (if applicable). Try to provide clear, step-by-
step instructions wherever possible.
##### Issues & Contribution Info
In this part, point users to any resources that can help them contribute to the
project. Include contribution guidelines and any specific instructions related
to your development practices. Include a link to
##### Issues & contributions
In this section, point users to any resources that can help them contribute to
the project. Include contribution guidelines and any specific instructions
related to your development practices. Include a link to
[Dockers resources for contributors](https://docs.docker.com/contributing/contributing/).
Be sure to include contact info, handles, etc. for official maintainers.
##### Issues
Include a brief section letting users know where they can go for help and how
Also include information letting users know where they can go for help and how
they can file issues with the repo. Point them to any specific IRC channels,
issue trackers, contacts, additional “how-to” information or other resources.
@ -122,8 +125,9 @@ issue trackers, contacts, additional “how-to” information or other resources
Include a file, `LICENSE`, of any applicable license. Docker recommends using
the license of the software contained in the image, provided it allows Docker,
Inc. to legally build and distribute the image. Otherwise Docker recommends
adopting the [Expat license](http://directory.fsf.org/wiki/License:Expat).
Inc. to legally build and distribute the image. Otherwise, Docker recommends
adopting the [Expat license](http://directory.fsf.org/wiki/License:Expat)
(a.k.a., the MIT or X11 license).
## Examples
@ -157,7 +161,7 @@ Put this file in the root of your app, next to the `Gemfile`.
This image includes multiple `ONBUILD` triggers so that should be all that you need for most applications. The build will `ADD . /usr/src/app`, `RUN bundle install`, `EXPOSE 3000`, and set the default command to `rails server`.
Then build and run the docker image.
Then build and run the Docker image.
docker build -t my-rails-app .
docker run --name some-rails-app -d my-rails-app
@ -166,7 +170,7 @@ Test it by visiting `http://container-ip:3000` in a browser. On the other hand,
docker run --name some-rails-app -p 8080:3000 -d my-rails-app
Then hit `http://localhost:8080` or `http://host-ip:8080` in a browser.
Then go to `http://localhost:8080` or `http://host-ip:8080` in a browser.
```
For more examples, take a look at these repos:
@ -176,3 +180,10 @@ For more examples, take a look at these repos:
* [Buildpack-deps](https://github.com/docker-library/buildpack-deps)
* ["Hello World" minimal container](https://github.com/docker-library/hello-world)
* [Node](https://github.com/docker-library/node)
## Submit your repo
Once you've checked off everything in these guidelines, and are confident your
image is ready for primetime, please contact us at
[partners@docker.com](mailto:partners@docker.com) to have your project
considered for the Official Repos program.

View file

@ -241,6 +241,15 @@ ol li {
margin-top: 10px;
}
.content-body h4 {
font-size: 16px;
font-weight: 400;
color: #394d54;
line-height: 1.7;
margin-bottom: 4px;
margin-top: 10px;
}
.content-body p {
font-size: 14px;
font-weight: 400;