Browse code

Edits and fixes to Dockerfile Best Practices based on review feedback.

Docker-DCO-1.1-Signed-off-by: Fred Lifton <fred.lifton@docker.com> (github: fredlf)

Fred Lifton authored on 2014/09/25 08:05:35
Showing 2 changed files
... ...
@@ -2,7 +2,7 @@ page_title: Best Practices for Writing Dockerfiles
2 2
 page_description: Hints, tips and guidelines for writing clean, reliable Dockerfiles
3 3
 page_keywords: Examples, Usage, base image, docker, documentation, dockerfile, best practices, hub, official repo
4 4
 
5
-# Best Practices for Writing Dockerfiles
5
+# Best practices for writing Dockerfiles
6 6
 
7 7
 ## Overview
8 8
 
... ...
@@ -23,7 +23,7 @@ You can see many of these practices and recommendations in action in the [buildp
23 23
 > Note: for more detailed explanations of any of the Dockerfile commands
24 24
 >mentioned here, visit the [Dockerfile Reference](https://docs.docker.com/reference/builder/) page.
25 25
 
26
-## General Guidelines and Recommendations
26
+## General guidelines and recommendations
27 27
 
28 28
 ### Containers should be ephemeral
29 29
 
... ...
@@ -42,7 +42,8 @@ megabytes worth of upload time.
42 42
 
43 43
 ### Avoid installing unnecessary packages
44 44
 
45
-In order to reduce complexity, dependencies, file sizes and build times, you should avoid installing extra or unnecessary packages just because they
45
+In order to reduce complexity, dependencies, file sizes, and build times, you
46
+should avoid installing extra or unnecessary packages just because they
46 47
 might be “nice to have.” For example, you don’t need to include a text editor
47 48
 in a database image.
48 49
 
... ...
@@ -75,7 +76,7 @@ Here’s an example from the [`buildpack-deps` image](https://github.com/docker-
75 75
       mercurial \
76 76
       subversion
77 77
 
78
-### Build Cache
78
+### Build cache
79 79
 
80 80
 During the process of building an image Docker will step through the
81 81
 instructions in your `Dockerfile` executing each in the order specified.
... ...
@@ -118,7 +119,7 @@ generate new images and the cache will not be used.
118 118
         mercurial \
119 119
         subversion
120 120
 
121
-## The `Dockerfile` instructions
121
+## The Dockerfile instructions
122 122
 
123 123
 Below you'll find recommendations for the best way to write the
124 124
 various instructions available for use in a `Dockerfile`.
... ...
@@ -133,29 +134,25 @@ since it’s very tightly controlled and kept extremely minimal (currently under
133 133
 ### [`RUN`](https://docs.docker.com/reference/builder/#run)
134 134
 
135 135
 As always, to make your `Dockerfile` more readable, understandable, and
136
-maintainable, put long or complex `RUN` statements on multiple lines separate
136
+maintainable, put long or complex `RUN` statements on multiple lines separated
137 137
 with backslashes.
138 138
 
139
-Probably the most common use-case for `RUN` is an application of `apt-get`
140
-When using `apt-get`, here a few things to keep in mind:
139
+Probably the most common use-case for `RUN` is an application of `apt-get`.
140
+When using `apt-get`, here are a few things to keep in mind:
141 141
 
142 142
 * Don’t do `RUN apt-get update` on a single line. This will cause
143 143
 caching issues if the referenced archive gets updated, which will make your
144 144
 subsequent `apt-get install` fail without comment.
145 145
 
146
-* For the most part, to keep your code more readable and maintainable, avoid instructions like:
147
-
148
-    RUN apt-get install -y package-foo && apt-get install -y package-bar
149
-
150 146
 * Avoid `RUN apt-get upgrade` or `dist-upgrade`, since many of the “essential”
151 147
 packages from the base images will fail to upgrade inside an unprivileged
152 148
 container. If a base package is out of date, you should contact its
153 149
 maintainers. If you know there’s a particular package, `foo`, that needs to be
154 150
 updated, use `apt-get install -y foo` and it will update automatically.
155 151
 
156
-* Do write something like:
152
+* Do write instructions like:
157 153
 
158
-    `RUN apt-get update && apt-get install -y package-bar package-foo package-baz`.
154
+    RUN apt-get update && apt-get install -y package-bar package-foo package-baz
159 155
 
160 156
 Writing the instruction this way not only makes it easier to read
161 157
 and maintain, but also, by including `apt-get update`, ensures that the cache
... ...
@@ -165,7 +162,7 @@ further coding or manual intervention required.
165 165
 * Further natural cache-busting can be realized by version-pinning packages
166 166
 (e.g., `package-foo=1.3.*`). This will force retrieval of that version
167 167
 regardless of what’s in the cache.
168
-Forming your `apt-get` code this way will greatly ease maintenance and reduce
168
+Writing your `apt-get` code this way will greatly ease maintenance and reduce
169 169
 failures due to unanticipated changes in required packages.
170 170
 
171 171
 #### Example
... ...
@@ -196,6 +193,11 @@ the new version (which in this case had a new, required feature).
196 196
         ruby1.9.1-dev \
197 197
         s3cmd=1.1.0*
198 198
 
199
+Writing the instruction this way also helps you avoid potential duplication of
200
+a given package because it is much easier to read than an instruction like:
201
+
202
+    RUN apt-get install -y package-foo && apt-get install -y package-bar
203
+    
199 204
 ### [`CMD`](https://docs.docker.com/reference/builder/#cmd)
200 205
 
201 206
 The `CMD` instruction should be used to run the software contained by your
... ...
@@ -290,7 +292,11 @@ is much easier to understand than
290 290
 
291 291
 ....docker run -it --entrypoint bash official-image -i
292 292
 
293
-especially for Docker beginners.
293
+This is especially true for new Docker users, who might naturally assume the
294
+above command will work fine. In cases where an image uses `ENTRYPOINT` for
295
+anything other than just a wrapper script, the command will fail and the
296
+beginning user will then be forced to learn about `ENTRYPOINT` and
297
+`--entrypoint`.
294 298
 
295 299
 In order to avoid a situation where commands are run without clear visibility
296 300
 to the user, make sure your script ends with something like `exec "$@"`. After
... ...
@@ -339,9 +345,9 @@ If a service can run without privileges, use `USER` to change to a non-root
339 339
 user. Start by creating the user and group in the `Dockerfile` with something
340 340
 like `RUN groupadd -r postgres && useradd -r -g postgres postgres`.
341 341
 
342
->**Note** Users and groups in an image get a non-deterministic
343
->UID/GID in that the “next” UID/GID gets assigned regardless of image
344
->rebuilds. So, if it’s critical, you should assign an explicit UID/GID.
342
+> **Note:** Users and groups in an image get a non-deterministic
343
+> UID/GID in that the “next” UID/GID gets assigned regardless of image
344
+> rebuilds. So, if it’s critical, you should assign an explicit UID/GID.
345 345
 
346 346
 You should avoid installing or using `sudo` since it has unpredictable TTY and
347 347
 signal-forwarding behavior that can cause more more problems than it solves. If
... ...
@@ -41,7 +41,7 @@ Your `Dockerfile` should adhere to the following:
41 41
 established Official Image.
42 42
 * It must follow `Dockerfile` best practices. These are discussed on the
43 43
 [best practices page](/articles/dockerfile_best-practices). In addition,
44
-Docker engineer Michael Crosby has some good tips for Dockerfiles in
44
+Docker engineer Michael Crosby has some good tips for `Dockerfiles` in
45 45
 this [blog post](http://crosbymichael.com/dockerfile-best-practices-take-2.html).
46 46
 
47 47
 While [`ONBUILD` triggers](https://docs.docker.com/reference/builder/#onbuild)
... ...
@@ -77,7 +77,7 @@ can be made based on the logo needed
77 77
 
78 78
 ### A long description
79 79
 
80
-Include a comprehensive description of your image (in markdown format, GitHub 
80
+Include a comprehensive description of your image (in Markdown format, GitHub 
81 81
 flavor preferred). Only one description is required; you don’t need additional
82 82
 descriptions for each tag. The file should also: 
83 83
 
... ...
@@ -88,9 +88,9 @@ content requirements
88 88
 
89 89
 In terms of content, the long description must include the following sections:
90 90
 
91
-* Overview & Links
92
-* How-to/Usage
93
-* Issues & Contribution Info
91
+* Overview & links
92
+* How-to/usage
93
+* Issues & contributions
94 94
 
95 95
 #### Overview & links
96 96
 
... ...
@@ -109,15 +109,15 @@ A section that describes how to run and use the image, including common use
109 109
 cases and example `Dockerfile`s (if applicable). Try to provide clear, step-by-
110 110
 step instructions wherever possible.
111 111
 
112
-##### Issues & contribution info
112
+##### Issues & contributions
113
+
113 114
 In this section, point users to any resources that can help them contribute to
114 115
 the project. Include contribution guidelines and any specific instructions
115 116
 related to your development practices. Include a link to
116 117
 [Docker’s resources for contributors](https://docs.docker.com/contributing/contributing/).
117 118
 Be sure to include contact info, handles, etc. for official maintainers.
118 119
 
119
-##### Issues
120
-Include a brief section letting users know where they can go for help and how
120
+Also include information letting users know where they can go for help and how
121 121
 they can file issues with the repo. Point them to any specific IRC channels,
122 122
 issue trackers, contacts, additional “how-to” information or other resources.
123 123
 
... ...
@@ -125,8 +125,9 @@ issue trackers, contacts, additional “how-to” information or other resources
125 125
 
126 126
 Include a file, `LICENSE`, of any applicable license.  Docker recommends using
127 127
 the license of the software contained in the image, provided it allows Docker,
128
-Inc. to legally build and distribute the image.  Otherwise, Docker recommends
129
-adopting the [Expat license](http://directory.fsf.org/wiki/License:Expat).
128
+Inc. to legally build and distribute the image. Otherwise, Docker recommends
129
+adopting the [Expat license](http://directory.fsf.org/wiki/License:Expat)
130
+(a.k.a., the MIT or X11 license).
130 131
 
131 132
 ## Examples
132 133
 
... ...
@@ -160,7 +161,7 @@ Put this file in the root of your app, next to the `Gemfile`.
160 160
 
161 161
 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`.
162 162
 
163
-Then build and run the docker image.
163
+Then build and run the Docker image.
164 164
 
165 165
     docker build -t my-rails-app .
166 166
     docker run --name some-rails-app -d my-rails-app
... ...
@@ -169,7 +170,7 @@ Test it by visiting `http://container-ip:3000` in a browser. On the other hand,
169 169
 
170 170
     docker run --name some-rails-app -p 8080:3000 -d my-rails-app
171 171
 
172
-Then hit `http://localhost:8080` or `http://host-ip:8080` in a browser.
172
+Then go to `http://localhost:8080` or `http://host-ip:8080` in a browser.
173 173
 ```
174 174
 
175 175
 For more examples, take a look at these repos: 
... ...
@@ -182,4 +183,7 @@ For more examples, take a look at these repos:
182 182
 
183 183
 ## Submit your repo
184 184
 
185
-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.
185
+Once you've checked off everything in these guidelines, and are confident your
186
+image is ready for primetime, please contact us at
187
+[partners@docker.com](mailto:partners@docker.com) to have your project
188
+considered for the Official Repos program.