Merge pull request #8222 from fredlf/adding_official-repo-guidelines
Edits and fixes based on review.
This commit is contained in:
commit
95e169a6a1
3 changed files with 105 additions and 64 deletions
|
@ -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
|
|||
you’re 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 you’re 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 don’t need to include a text editor
|
||||
in a database image.
|
||||
|
||||
|
@ -75,7 +76,7 @@ Here’s 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
|
||||
it’s 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 it’s 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:
|
||||
|
||||
* 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
|
||||
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 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
|
||||
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 what’s 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 it’s 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 it’s 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)
|
||||
|
|
|
@ -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 don’t 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 don’t 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
|
||||
[Docker’s 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.
|
||||
|
|
9
docs/theme/mkdocs/css/docs.css
vendored
9
docs/theme/mkdocs/css/docs.css
vendored
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue