Dockerfile 最佳實務

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Dockerfile 最佳實務

Why

Docker 作為非常優秀的輕量級 PaaS 解決方案,得到了主流雲端服務平台的先後支援,配合 Docker Registry Hub 提供高品質的 Docker Image 以及 Fig 進行 Containers 的管理,吸引了全球的開發人員將自己的服務遷移到 Docker Containers 上面,從而提高開發和部署效率。作為快速發展的新技術,很多高品質的技術文章和使用經驗都是英文的,我自己在學習 Docker 的過程中,在不同的網站和個人 Blog 就看到過很多,所以,就想著把我看到的高品質文章翻譯過來放在這個 Blog,一方面翻譯的過程是加深理解的過程,另一方面把散落在各處的好文章集中在一個地方並翻譯成中文,便於之後的分享以及回顧。

What

本文譯文部分翻譯自 Dockerfile Best Practices,英文著作權歸 原作者 所有,譯文轉載請註明出處。

譯文

Dockerfile 對建立 Docker Image 提供了簡單的文法,本文記錄一些可以讓我們真正用好 Dockerfile 的一些技巧和經驗。

在 Dockerfile 的最開始部分保持通用建立指示內容以利用緩衝

Dockerfile 中的每一條指示執行後的結果都會提交到新建立的 Image 中,並作為下一條指示執行的基礎。如果已經存在一個擁有相同父 Image 而且該 Image 的 Dockerfile 有相同的指示(除了 ADD)的另一個 Image,Docker 將會使用這個已存在的 Image 而不是重新通過執行每一條 Dockrfile 中的指示來建立另一個新的 Image,這就是緩衝機制。

為了能夠能有效地利用緩衝,我們需要盡量保持 Dockerfiles 的一致性,並且將不同的指示放在 Dockerfile 最後的部分,所有我自己的 Dockerfiles 都以下面 5 行開始:

FROM ubuntuMAINTAINER Michael Crosby <michael@crosbymichael.com>RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.listRUN apt-get updateRUN apt-get upgrade -y

注意,改變 MAINTAINER 指示將會迫使 Docker 放棄使用緩衝並重新通過執行 RUN 指示的操作。

在建立 Docker Image 的時候使用 -t 參數對 Image 打上 Tag

如果我們不是僅僅對 Docker 嘗嘗鮮試用一下,那我們應該在建立 Docker Image 的時候使用 -t 參數對 Image 打上 Tag,因為一個有意義的 Tag 名可以協助我們明確建立這個 Image 的目的。

docker build -t=”crosbymichael/sentry” .

不要在 Dockerfile 中進行連接埠映射

Docker 的兩個最核心的特性就是可重複性和可移植性。Image 應該可以被根據需要用來在任何 host 上建立多個 Containers,考慮到這點,雖然我們在 Dockerfile 中可以映射 Container 連接埠到 host 連接埠,但是我們永遠不應該在 Dockerfile 中這麼做,否則我們就只能使用該 Dockerfile 建立的 Image 建立一個 Container。

# private and public mappingEXPOSE 80:8080# private onlyEXPOSE 80

如果 Image 的使用者關心 Container 應該將自己的什麼連接埠和 host 的連接埠進行映射,那就會顯式地在建立 Container 的時候使用 -p 參數進行設定,否則,Docker 會自動給 Container 分配一個 host 上的連接埠進行映射。

在使用 CMDENTRYPOINT 指示的時候使用資料傳入參數

CMDENTRYPOINT 指示的作用是容易理解的,但是它們有個隱藏的坑,如果不注意就可能會導致錯誤發生。這兩個指示都支援下面的文法:

CMD /bin/echo# orCMD ["/bin/echo"]

看上去好像沒什麼,但是隱藏在細節中的坑卻可能真的會坑人。如果我們使用下面以數組方式傳遞參數的方式,最後的結果會和我們預期的相同;但是當我們使用第一種文法時,由於 Docker 會自動在需要執行的命令前加上 /bin/sh -c,這種情況下可能會導致一些未預料的錯誤和不好理解的事情發生,所以總是使用數組傳遞參數是個好主意,這能保證命令按照我們預期的方式被執行。

CMDENTRYPOINT 最好配合使用

ENTRYPOINT 會讓我們的 Container 使用起來像個可執行檔,我們可以在使用 docker run 建立 Container 的時候傳遞參數給 ENTRYPOINT 執行並且不用擔心操作被覆蓋(就像使用 CMD 後的情況)。在和 CMD 一起配合使用時 ENTRYPOINT 甚至能提供更好的體驗,我們通過一個 Rethinkdb 的例子來看看怎麼用:

# Dockerfile for Rethinkdb # http://www.rethinkdb.com/FROM ubuntuMAINTAINER Michael Crosby <michael@crosbymichael.com>RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.listRUN apt-get updateRUN apt-get upgrade -yRUN apt-get install -y python-software-propertiesRUN add-apt-repository ppa:rethinkdb/ppaRUN apt-get updateRUN apt-get install -y rethinkdb# Rethinkdb processEXPOSE 28015# Rethinkdb admin consoleEXPOSE 8080# Create the /rethinkdb_data dir structureRUN /usr/bin/rethinkdb createENTRYPOINT ["/usr/bin/rethinkdb"]CMD ["--help"]

這就是我們將 Rethinkdb 遷移到 Docker 需要做的全部事情。最前面的 5 行是我自己的 Dockerfile 的標準開頭,接下來是一些安裝和必要的連接埠暴露等,最後使用 ENTRYPOINT。我們知道當我們使用該 Dockerfile 建立的 Image 來建立一個 Container 並啟動並執行時候,所有通過 docker run 命令傳遞的參數都會被傳遞給 ENTRYPOINT(/usr/bin/rethinkdb)。但是可以看到 ENTRYPOINT 指示下面還有一條 CMD 指示並擁有 –help 的內容,這樣就會在當我們在使用 docker run 建立 Container 的時候沒有傳遞參數的時候顯示 rethinkdb 的協助內容,就像這樣:

docker run crosbymichael/rethinkdb

輸出為:

Running 'rethinkdb' will create a new data directory or use an existing one,  and serve as a RethinkDB cluster node.File path options:  -d [ --directory ] path           specify directory to store data and metadata  --io-threads n                    how many simultaneous I/O operations can happen                                    at the same timeMachine name options:  -n [ --machine-name ] arg         the name for this machine (as will appear in                                    the metadata).  If not specified, it will be                                    randomly chosen from a short list of names.Network options:  --bind {all | addr}               add the address of a local interface to listen                                    on when accepting connections; loopback                                    addresses are enabled by default  --cluster-port port               port for receiving connections from other nodes  --driver-port port                port for rethinkdb protocol client drivers  -o [ --port-offset ] offset       all ports used locally will have this value                                    added  -j [ --join ] host:port           host and port of a rethinkdb node to connect to  .................

現在我們再看看如果傳遞了 “–bind all” 的參數後發生什麼:

docker run crosbymichael/rethinkdb --bind all

輸出為:

info: Running rethinkdb 1.7.1-0ubuntu1~precise (GCC 4.6.3)...info: Running on Linux 3.2.0-45-virtual x86_64info: Loading data from directory /rethinkdb_datawarn: Could not turn off filesystem caching for database file: "/rethinkdb_data/metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/auth_metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.info: Listening for intracluster connections on port 29015info: Listening for client driver connections on port 28015info: Listening for administrative HTTP connections on port 8080info: Listening on addresses: 127.0.0.1, 172.16.42.13info: Server readyinfo: Someone asked for the nonwhitelisted file /js/handlebars.runtime-1.0.0.beta.6.js, if this should be accessible add it to the whitelist.

就是這樣,一個完整的 Rethinkdb 執行個體,可以像在 host 上使用 Rethinkdb 的可執行檔一樣來進行互動,很簡單。

我希望這篇文章能協助大家善用 Dockerfile 建立自己的 Image 並分享出來。我相信 Dockerfile 是 Docker 之所以非常簡單易用的一個重要原因。

Dockerfile 最佳實務 續

-- EOF --

  • 理解 Docker 中的 Volumes→
  • ← 使用 Fig 管理 Flask 和 Nginx 的開發環境

聲明: 本文採用 BY-NC-SA 協議進行授權. 轉載請註明轉自: Dockerfile 最佳實務

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.