【Docker】來自官方映像的 6 個 Dockerfile 技巧

 本文將根據我從官方鏡像學到的經驗,講解編寫Dockerfile的技巧。html

 

 

  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 nginx

 

 

參考資料:redis

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

相關文章
相關標籤/搜索