本文将根据我从官方镜像学到的经验,讲解编写Dockerfile的技巧。

 

  1. 选择Debian 

  官方镜像的大多数Dockerfile,不管是直接还是通过其他镜像,都是基于Debian的。Dockerfile版本通常跟特定的发行版挂钩,正常是使用稳定版(wheezy),有些是测试版(jessie),还有是不稳定版(sid)。Debian镜像的主要好处是文件小,加起来才85.1MB,而Ubuntu要200MB。指定准确的发行版可以预防一些问题,比如,即使标上latest的发行版升级了,构建也不会崩溃。 

  2. 确定来源 

  如果要用户信赖你的镜像,你就要考虑如果验证此镜像上的所有软件的真实性。如果通过apt-get方式从Debian的仓库获取,这个验证过程已经被解决了。如果从网上下载文件,或者从第三方仓库安装软件,你就应该通过校验和、数字签名等方式验证这些文件。比如,为了验证nginx包,nginx的Dockerfile会做如下操作: 

  RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 

  RUN echo "deb http://nginx.org/packages/mainline/debian/ wheezy nginx" >> /etc/apt/sources.list 

  ENV NGINX_VERSION 1.7.7-1~wheezy 

  RUN apt-get update && apt-get install -y nginx=${NGINX_VERSION} 

  注意nginx也是跟一个特定的版本关联的。这种做法可以保证,维护者测试的镜像跟构建工具构建的是相同的。但是,这个假设也不是绝对的,因为nginx本身的依赖也会随时间变化(比如有些依赖会标明>=某个版本)。 

  你自己也可以对下载的文件做相似的操作,计算文件校验和,然后跟本地版本(stored version)比较。这些操作都由Redis Dockerfile做过了。另外,有些下载的文件可能包含签名文件,你可以通过gpg来验证,通常这些操作都由官方镜像做过了。 

  不幸的是,一些官方镜像也没能定期正确地进行这些验证操作,或者只验证了部分文件,所以查看官方Dockerfile时要注意下。 

  3. 移除构建依赖 

  如果通过源码编译构建,你的镜像通常比需要的大很多。可能的话,在同一条RUN指令中,安装构建工具、构建软件,然后移除构建工具。虽然这样做又诡异又恼人,但是可以省下几百MB空间。在不同的指令中删除文件是没有意义的,因为这些文件已经被打包进镜像了。我们看下Redis Dockerfile是怎么做的: 

  RUN buildDeps='gcc libc6-dev make'; \ 

  set -x \ 

  && apt-get update && apt-get install -y $buildDeps --no-install-recommends \ 

  && rm -rf /var/lib/apt/lists/* \ 

  && mkdir -p /usr/src/redis \ 

  && curl -sSL "$REDIS_DOWNLOAD_URL" -o redis.tar.gz \ 

  && echo "$REDIS_DOWNLOAD_SHA1 *redis.tar.gz" | sha1sum -c - \ 

  && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ 

  && rm redis.tar.gz \ 

  && make -C /usr/src/redis \ 

  && make -C /usr/src/redis install \ 

  && ln -s redis-server "$(dirname "$(which redis-server)")/redis-sentinel" \ 

  && rm -r /usr/src/redis \ 

  && apt-get purge -y --auto-remove $buildDeps 

  gcc, libc和make在同一条指令中先被安装,使用,然后被删掉。另外注意下,作者还删除了不会被使用的tar.gz源文件夹。顺带提下,这些代码也演示了如何使用sha1sum来验证Redis下载文件的校验和。 

  4. 选择gosu 

  gosu实用工具,通常用在ENTRYPOINT指令调用的脚本中,这些ENTRYPOINT指令位于官方镜像的Dockerfile中。它是个类sudo的简单工具,接受并运行特定用户的特定指令。但是gosu可以避免sudo怪异恼人的TTY和信号转发(signal-forwarding)行为。 

  看下这篇编写入口点脚本的官方建议https://docs.docker.com/articles/dockerfile_best-practices/,大多数官方镜像都遵循该建议。 

  5. 选择buildpack-deps基础镜像 

  很多Docker的"language-stack"镜像都是基于 buildpack-deps 基 础镜像,该镜像包含了通常开发所必须的头文件和工具(比如源码管理工具)。如果你想构建一个language-stack镜像,使用这个基础镜像可以省下 不少时间。但是向镜像添加非必须的东西也遭受了很多批评,这导致了一些仓库,如Node提供了直接基于Debian的可选slim包(完整的Node镜像 有728MB,slim只有291.4MB)。但是记住用户可能需要某些开发库,同时也通过某种途径下载了基础镜像。 

  6. 使用描述性标签 

  所有的官方镜像都提供了很多标签。像latest标签一样,提供一个版本标签是种好做法,这样用户就不用担心基础镜像变更而破坏容器。官方镜像做了更多, 提供了上文提及的精简slim镜像,以及自动导入和编译的onbuild镜像。镜像打上onbuild标签,即使转移代码再编译,来新建子镜像,用户也不会太意外。原文 

  原文出自:http://www.oschina.net/translate/6-dockerfile-tips-official-images

参考资料:

http://www.cstor.cn/textdetail_7886.html

【Docker】来自官方映像的 6 个 Dockerfile 技巧的更多相关文章

  1. Docker 中国官方镜像加速

    参考:https://www.docker-cn.com/registry-mirror 通过 Docker 官方镜像加速,中国区用户能够快速访问最流行的 Docker 镜像.该镜像托管于中国大陆,本 ...

  2. Docker 使用官方镜像

    Docker 使用官方镜像 如何使用官方镜像 Docker 中国官方镜像加速可通过 registry.docker-cn.com 访问.目前该镜像库只包含流行的公有镜像,而私有镜像仍需要从美国镜像库中 ...

  3. 详解如何使用Docker Hub官方的MySQL镜像生成容器

    一直在尝试以官方CentOS镜像为基础,制作基于CentOS的MySQL镜像.但是制作后发现镜像大小已经超过1.5G,这对于一般的Docker镜像来说太臃肿了.Docker Hub官方提供的CentO ...

  4. 配置Docker中国区官方镜像http://get.daocloud.io/ 很好的一个源http://get.daocloud.io/#install-docker

    https://www.daocloud.io/mirror#accelerator-doc 配置Docker中国区官方镜像http://get.daocloud.io/ 很好的一个源http://g ...

  5. 【转载】使用Docker Hub官方gcc:latest镜像编译C/C++程序以及缩小镜像的方法

    摘要:使用Docker Hub官方gcc:latest镜像(1.2GB)编译C/C++程序,以及缩小镜像的方法. 方法1: 在gcc容器里编译C/C++程序 将C/C++代码运行在gcc容器内的最简单 ...

  6. edgedb-js 来自官方的js 驱动

    目前对于edgedb 主要还是来自官方的python驱动,目前js 版本的已经快发布了,代码在github 可以看到了 同时官方文档也提供了一个关于edgedb 内部的协议说明,结合js 驱动以及文档 ...

  7. cube.js 学习(十)cube 来自官方的学习网站

    尽管cube.js 包含了一个doc 站点,但是资料不是很全,同时如果查看了cube github 代码中的一些demo的话,发现还是很不错的 但是一些实践没有在文档展现出来,还好我们可以从cube ...

  8. docker MySQL官方版本使用记录

    docker MySQL官方版本使用记录 使用记录 拉取官方镜像:docker pull mysql 运行镜像:docker run --name mysql -p 3306:3306 -e MYSQ ...

  9. 体验SpringBoot(2.3)应用制作Docker镜像(官方方案)

    关于<SpringBoot-2.3容器化技术>系列 <SpringBoot-2.3容器化技术>系列,旨在和大家一起学习实践2.3版本带来的最新容器化技术,让咱们的Java应用更 ...

随机推荐

  1. 在Oracle里,表的别名不能用as,列的别名可以用as

    列的别名也可以不用as,如:select t.a xxx from table t 在Oracle数据库中,数据表别名是不能加as的,例如: select a.appname from appinfo ...

  2. Session的异常

    既然这一天就这么废了,那就多说一些吧!其实session也是有潜在的问题的.Session销毁的三种情况: (1)超时:超过30分钟 (2)服务器非正常关闭,如果自己手动stop service而不是 ...

  3. NS图绘制工具推荐

    世界上要画NS图的人肯定很少,这种无聊的东西= = 我根据个人经验和直觉,推荐三个套工具. 一.签字笔(铅笔+橡皮)+作业纸+拍照的手机 鉴于我以前手绘版ns图已经找不到了,就用室友之前画的做个例子. ...

  4. 查询条件Where

    1.字符串 $condition = 'name=\'Lily\' and age>10'; 2.数组 ['type' => 1, 'status' => 1] //生成 (type ...

  5. mac os x常用快捷键及用法

    最近在研究mac os x系统,开始入手,很不习惯,和windows差别很大,毕竟unix内核.使用中总结了一些使用快捷键(默认),持续更新,欢迎大家补充.1.撤销:command+z 保存:comm ...

  6. request.getAttribute() 和 request.getParameter() 有何区别?

    HttpServletRequest类既有getAttribute()方法,也由getParameter()方法,这两个方法有以下区别: (1)HttpServletRequest类有setAttri ...

  7. 【SDOI2008】解题汇总

    好叭我真的是闲的了... /---------------------------------------------/ BZOJ-2037 [SDOI2008]Sue的小球 DP+相关费用提前计算 ...

  8. BZOJ-1189 紧急疏散evacuate BFS预处理+最大流+二分判定+神建模!!

    绝世污题,垃圾题,浪费我一整天青春! 1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1262 ...

  9. Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子

    实现一个控制器ShirdrnController,如下所示: package org.shirdrn.spring.mvc; import java.util.Date; import javax.s ...

  10. Windows 下安装项目管理工具 Redmine 1.1.2

    1.InstantRails-2.0-win 下载地址  https://rubyforge.org/frs/?group_id=904 2.redmine1.1.2 下载地址  http://www ...