PageRenderTime 25ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/build_defs/docker/README.md

https://gitlab.com/18runt88/bazel
Markdown | 457 lines | 406 code | 51 blank | 0 comment | 0 complexity | d9b83a02104a257e01f1769443c33223 MD5 | raw file
  1. # Docker support for Bazel
  2. <div class="toc">
  3. <h2>Rules</h2>
  4. <ul>
  5. <li><a href="#docker_build">docker_build</a></li>
  6. </ul>
  7. </div>
  8. ## Overview
  9. These build rules are used for building [Docker](https://www.docker.com)
  10. images. Such images are easy to modify and deploy system image for
  11. deploying application easily on cloud providers.
  12. As traditional Dockerfile-based `docker build`s effectively execute a series
  13. of commands inside of Docker containers, saving the intermediate results as
  14. layers; this approach is unsuitable for use in Bazel for a variety of reasons.
  15. The docker_build rule constructs a tarball that is compatible with
  16. `docker save/load`, and creates a single layer out of each BUILD rule in the chain.
  17. * [Basic Example](#basic-example)
  18. * [Build Rule Reference](#reference)
  19. * [Future work](#future)
  20. <a name="basic-example"></a>
  21. ## Basic Example
  22. Consider the following BUILD file in `//third_party/debian`:
  23. ```python
  24. load("/tools/build_defs/docker/docker", "docker_build")
  25. filegroup(
  26. name = "ca_certificates",
  27. srcs = ["ca_certificates.deb"],
  28. )
  29. # Example when you have all your dependencies in your repository.
  30. # We have an example on how to fetch them from the web later in this
  31. # document.
  32. filegroup(
  33. name = "openjdk-7-jre-headless",
  34. srcs = ["openjdk-7-jre-headless.deb"],
  35. )
  36. docker_build(
  37. name = "wheezy",
  38. tars = ["wheezy.tar"],
  39. )
  40. ```
  41. The `wheezy` target in that BUILD file roughly corresponds to the Dockerfile:
  42. ```docker
  43. FROM scratch
  44. ADD wheezy.tar /
  45. ```
  46. You can then build up subsequent layers via:
  47. ```python
  48. docker_build(
  49. name = "base",
  50. base = "//third_party/debian:wheezy",
  51. debs = ["//third_party/debian:ca_certificates"],
  52. )
  53. docker_build(
  54. name = "java",
  55. base = ":base",
  56. debs = ["//third_party/debian:openjdk-7-jre-headless"],
  57. )
  58. ```
  59. ## Metadata
  60. You can set layer metadata on these same rules by simply adding (supported) arguments to the rule, for instance:
  61. ```python
  62. docker_build(
  63. name = "my-layer",
  64. entrypoint = ["foo", "bar", "baz"],
  65. ...
  66. )
  67. ```
  68. Will have a similar effect as the Dockerfile construct:
  69. ```docker
  70. ENTRYPOINT ["foo", "bar", "baz"]
  71. ```
  72. For the set of supported metadata, and ways to construct layers, see here.
  73. ### Using
  74. Suppose you have a `docker_build` target `//my/image:helloworld`:
  75. ```python
  76. docker_build(
  77. name = "helloworld",
  78. ...
  79. )
  80. ```
  81. You can build this with `bazel build my/image:helloworld.tar`.
  82. This will produce the file `bazel-genfiles/my/image/helloworld.tar`.
  83. You can load this into my local Docker client by running
  84. `docker load -i bazel-genfiles/my/image/helloworld.tar`, or simply
  85. `bazel run my/image:helloworld` (this last command only update the
  86. changed layers and thus is faster).
  87. Upon success you should be able to run `docker images` and see:
  88. ```
  89. REPOSITORY TAG IMAGE ID ...
  90. bazel/my_image helloworld d3440d7f2bde ...
  91. ```
  92. You can now use this docker image with the name `bazel/my_image:helloworld` or
  93. tag it with another name, for example:
  94. `docker tag bazel/my_image:helloworld gcr.io/my-project/my-awesome-image:v0.9`
  95. You can do all that at once with specifying the tag on the command line of
  96. `bazel run`:
  97. ```
  98. bazel run my/image:helloworld gcr.io/my-project/my-awesome-image:v0.9
  99. ```
  100. __Nota Bene:__ the `docker images` command will show a really old timestamp
  101. because `docker_build` remove all timestamps from the build to make it
  102. reproducible.
  103. ## Pulling images and deb files from the internet
  104. If you do not want to check in base image in your repository, you can use
  105. [external repositories](http://bazel.io/docs/external.html). For instance,
  106. you could create various layer with `external` labels:
  107. ```python
  108. load("/tools/build_defs/docker/docker", "docker_build")
  109. docker_build(
  110. name = "java",
  111. base = "@docker-debian//:wheezy",
  112. debs = ["@openjdk-7-jre-headless//file"],
  113. )
  114. ```
  115. Using the WORKSPACE file to add the actual files:
  116. ```python
  117. new_http_archive(
  118. name = "docker-debian",
  119. url = "https://codeload.github.com/tianon/docker-brew-debian/zip/e9bafb113f432c48c7e86c616424cb4b2f2c7a51",
  120. build_file = "debian.BUILD",
  121. type = "zip",
  122. sha256 = "515d385777643ef184729375bc5cb996134b3c1dc15c53acf104749b37334f68",
  123. )
  124. http_file(
  125. name = "openjdk-7-jre-headless",
  126. url = "http://security.debian.org/debian-security/pool/updates/main/o/openjdk-7/openjdk-7-jre-headless_7u79-2.5.5-1~deb7u1_amd64.deb",
  127. sha256 = "b632f0864450161d475c012dcfcc37a1243d9ebf7ff9d6292150955616d71c23",
  128. )
  129. ```
  130. With the following `debian.BUILD` file:
  131. ```python
  132. load("/tools/build_defs/docker/docker", "docker_build")
  133. # Extract .xz files
  134. genrule(
  135. name = "wheezy_tar",
  136. srcs = ["docker-brew-debian-e9bafb113f432c48c7e86c616424cb4b2f2c7a51/wheezy/rootfs.tar.xz"],
  137. outs = ["wheezy_tar.tar"],
  138. cmd = "cat $< | xzcat >$@",
  139. )
  140. docker_build(
  141. name = "wheezy",
  142. tars = [":wheezy_tar"],
  143. visibility = ["//visibility:public"],
  144. )
  145. ```
  146. <a name="future"></a>
  147. ## Future work
  148. In the future, we would like to provide better integration with docker
  149. repositories: pull and push docker image.
  150. <a name="docker_build"></a>
  151. ## docker_build
  152. ```python
  153. docker_build(name, base, data_path, directory, files, mode, tars, debs, symlinks, entrypoint, cmd, env, labels, ports, volumes, workdir, repository)
  154. ```
  155. <table class="table table-condensed table-bordered table-implicit">
  156. <colgroup>
  157. <col class="col-param" />
  158. <col class="param-description" />
  159. </colgroup>
  160. <thead>
  161. <tr>
  162. <th colspan="2">Implicit output targets</th>
  163. </tr>
  164. </thead>
  165. <tbody>
  166. <tr>
  167. <td><code><i>name</i>.tar</code></td>
  168. <td>
  169. <code>The full Docker image</code>
  170. <p>
  171. A full Docker image containing all the layers, identical to
  172. what <code>docker save</code> would return. This is
  173. only generated on demand.
  174. </p>
  175. </td>
  176. </tr>
  177. <tr>
  178. <td><code><i>name</i>-layer.tar</code></td>
  179. <td>
  180. <code>An image of the current layer</code>
  181. <p>
  182. A Docker image containing only the layer corresponding to
  183. that target. It is used for incremental loading of the layer.
  184. </p>
  185. <p>
  186. <b>Note:</b> this target is not suitable for direct comsumption.
  187. It is used for incremental loading and non-docker rules should
  188. depends on the docker image (<i>name</i>.tar) instead.
  189. </p>
  190. </td>
  191. </tr>
  192. <tr>
  193. <td><code><i>name</i></code></td>
  194. <td>
  195. <code>Incremental image loader</code>
  196. <p>
  197. The incremental image loader. It will load only changed
  198. layers inside the Docker registry.
  199. </p>
  200. </td>
  201. </tr>
  202. </tbody>
  203. </table>
  204. <table class="table table-condensed table-bordered table-params">
  205. <colgroup>
  206. <col class="col-param" />
  207. <col class="param-description" />
  208. </colgroup>
  209. <thead>
  210. <tr>
  211. <th colspan="2">Attributes</th>
  212. </tr>
  213. </thead>
  214. <tbody>
  215. <tr>
  216. <td><code>name</code></td>
  217. <td>
  218. <code>Name, required</code>
  219. <p>A unique name for this rule.</p>
  220. </td>
  221. </tr>
  222. <tr>
  223. <td><code>base</code></td>
  224. <td>
  225. <code>File, optional</code>
  226. <p>
  227. The base layers on top of which to overlay this layer, equivalent to
  228. FROM.
  229. </p>
  230. </td>
  231. </tr>
  232. <tr>
  233. <td><code>data_path</code></td>
  234. <td>
  235. <code>String, optional</code>
  236. <p>Root path of the files.</p>
  237. <p>
  238. The directory structure from the files is preserved inside the
  239. docker image but a prefix path determined by `data_path`
  240. is removed from the directory structure. This path can
  241. be absolute from the workspace root if starting with a `/` or
  242. relative to the rule's directory. A relative path may starts with "./"
  243. (or be ".") but cannot use go up with "..". By default, the
  244. `data_path` attribute is unused and all files are supposed to have no
  245. prefix.
  246. </p>
  247. </td>
  248. </tr>
  249. <tr>
  250. <td><code>directory</code></td>
  251. <td>
  252. <code>String, optional</code>
  253. <p>Target directory.</p>
  254. <p>
  255. The directory in which to expand the specified files, defaulting to '/'.
  256. Only makes sense accompanying one of files/tars/debs.
  257. </p>
  258. </td>
  259. </tr>
  260. <tr>
  261. <td><code>files</code></td>
  262. <td>
  263. <code>List of files, optional</code>
  264. <p>File to add to the layer.</p>
  265. <p>
  266. A list of files that should be included in the docker image.
  267. </p>
  268. </td>
  269. </tr>
  270. <tr>
  271. <td><code>mode</code></td>
  272. <td>
  273. <code>String, default to 0555</code>
  274. <p>
  275. Set the mode of files added by the <code>files</code> attribute.
  276. </p>
  277. </td>
  278. </tr>
  279. <tr>
  280. <td><code>tars</code></td>
  281. <td>
  282. <code>List of files, optional</code>
  283. <p>Tar file to extract in the layer.</p>
  284. <p>
  285. A list of tar files whose content should be in the docker image.
  286. </p>
  287. </td>
  288. </tr>
  289. <tr>
  290. <td><code>debs</code></td>
  291. <td>
  292. <code>List of files, optional</code>
  293. <p>Debian package to install.</p>
  294. <p>
  295. A list of debian packages that will be installed in the docker image.
  296. </p>
  297. </td>
  298. </tr>
  299. <tr>
  300. <td><code>symlinks</code></td>
  301. <td>
  302. <code>Dictionary, optional</code>
  303. <p>Symlinks to create in the docker image.</p>
  304. <p>
  305. <code>
  306. symlinks = {
  307. "/path/to/link": "/path/to/target",
  308. ...
  309. },
  310. </code>
  311. </p>
  312. </td>
  313. </tr>
  314. <tr>
  315. <td><code>entrypoint</code></td>
  316. <td>
  317. <code>String or string list, optional</code>
  318. <p><a href="https://docs.docker.com/reference/builder/#entrypoint">List
  319. of entrypoints to add in the layer.</a></p>
  320. </td>
  321. </tr>
  322. <tr>
  323. <td><code>cmd</code></td>
  324. <td>
  325. <code>String or string list, optional</code>
  326. <p><a href="https://docs.docker.com/reference/builder/#cmd">List
  327. of commands to execute in the layer.</a></p>
  328. </td>
  329. </tr>
  330. <tr>
  331. <td><code>env</code></td>
  332. <td>
  333. <code>Dictionary from strings to strings, optional</code>
  334. <p><a href="https://docs.docker.com/reference/builder/#env">Dictionary
  335. from environment variable names to their values when running the
  336. docker image.</a></p>
  337. <p>
  338. <code>
  339. env = {
  340. "FOO": "bar",
  341. ...
  342. },
  343. </code>
  344. </p>
  345. </td>
  346. </tr>
  347. <tr>
  348. <td><code>labels</code></td>
  349. <td>
  350. <code>Dictionary from strings to strings, optional</code>
  351. <p><a href="https://docs.docker.com/reference/builder/#label">Dictionary
  352. from custom metadata names to their values. You can also put a
  353. file name prefixed by '@' as a value. Then the value is replaced
  354. with the contents of the file.
  355. <p>
  356. <code>
  357. labels = {
  358. "com.example.foo": "bar",
  359. "com.example.baz": "@metadata.json",
  360. ...
  361. },
  362. </code>
  363. </p>
  364. </td>
  365. </tr>
  366. <tr>
  367. <td><code>ports</code></td>
  368. <td>
  369. <code>String list, optional</code>
  370. <p><a href="https://docs.docker.com/reference/builder/#expose">List
  371. of ports to expose.</a></p>
  372. </td>
  373. </tr>
  374. <tr>
  375. <td><code>volumes</code></td>
  376. <td>
  377. <code>String list, optional</code>
  378. <p><a href="https://docs.docker.com/reference/builder/#volumes">List
  379. of volumes to mount.</a></p>
  380. </td>
  381. </tr>
  382. <tr>
  383. <td><code>workdir</code></td>
  384. <td>
  385. <code>String, optional</code>
  386. <p><a href="https://docs.docker.com/reference/builder/#workdir">Initial
  387. working directory when running the docker image.</a></p>
  388. <p>Because building the image never happen inside a docker container,
  389. this working directory does not affect the other actions (e.g.,
  390. adding files).</p>
  391. </td>
  392. </tr>
  393. <tr>
  394. <td><code>repository</code></td>
  395. <td>
  396. <code>String, default to `bazel`</code>
  397. <p>The repository for the default tag for the image.</a></p>
  398. <p>Image generated by `docker_build` are tagged by default to
  399. `bazel/package_name:target` for a `docker_build` target at
  400. `//package/name:target`. Setting this attribute to
  401. `gcr.io/dummy` would set the default tag to
  402. `gcr.io/dummy/package_name:target`.</p>
  403. </td>
  404. </tr>
  405. </tbody>
  406. </table>