阿里華為Dockerfile命令規範及最佳實踐

2020-12-21 JavaEdge

0 什麼是 Dockerfile?

Dockerfile 是一個用來構建鏡像的文本文件,文本內容包含了一條條構建鏡像所需的指令和說明。

1 FROM

定製的鏡像都是基於 FROM 的鏡像,後續的操作都是基於該 image。

FROM scratch製作base imageFROM centos使用base imageFROM ubuntu:14.04最佳實踐

考慮安全性,請儘量使用官方 image 作為 base image。

2 LABEL

LABEL maintainer= "javaedge@gmail.com'LABEL version="1.O"LABEL description="This is a description"最佳實踐

這就像代碼的注釋,必須寫好元數據。

3 RUN

用於執行後面跟著的命令行命令。有以下倆種格式:

Shell格式

RUN apt-get install -y vimCMD echo "hello docker"ENTRYPOINT echo "hello docker"Dockerfile

docker build -t javaedge/centos-shell .

docker image lsdocker run javaedge/centos-shell

RUN <命令行命令># <命令行命令> 等同於,在終端操作的 shell 命令。Exec 格式

RUN [ "apt-get" , "install" , "-y", "vim" ]CMD [ " /bin/echo" , "hello docker" ]ENTRYPOINT [ "/bin/echo" , "hello docker" ]Dockerfile2

那如何修改才能讓 exec 格式的命令能被 shell 識別呢,修正:

RUN ["可執行文件", "參數1", "參數2"]# 例如:# RUN ["./test.php", "dev", "offline"] 等價於 RUN ./test.php dev offlineRUN yum update && yum install -y vim \ python-dev # 反斜線換行RUN apt-get update && apt-get install -y perl \ pwgen --no-install-recommends && rm -rf \ /var/lib/apt/lists/* # 注意清理cacheRUN /bin/bash -C 'source $HOME/.bashrc; echo$HOME'Dockerfile 的指令每執行一次都會在 docker 上新建一層。所以過多無意義的層,會造成鏡像膨脹過大。例如:

FROM centosRUN yum install wgetRUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"RUN tar -xvf redis.tar.gz以上執行會創建 3 層鏡像。可簡化為以下格式:FROM centosRUN yum install wget \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && tar -xvf redis.tar.gz如上,以 && 符號連接命令,這樣執行後,只會創建 1 層鏡像。

最佳實踐

可讀性複雜RUN用反斜線換行避免無用分層合併多條命令成一行4 WORKDIR

類似 linux 的cd 命令。

WORKDIR /test # 如果沒有會自動創建test目錄WORKDIR demoRUN pwd # 輸出結果應為/test/demo最佳實踐

使用WORKDIR,不要用 RUN cd儘量使用絕對目錄而非相對目錄。

5 ADD & COPY

COPY

複製指令,從上下文目錄中複製文件或者目錄到容器裡指定路徑。

格式:

COPY [--chown=<user>:<group>] <源路徑1>... <目標路徑>COPY [--chown=<user>:<group>] ["<源路徑1>",... "<目標路徑>"][--chown=<user>:<group>]:可選參數,用戶改變複製到容器內文件的擁有者和屬組。

<源路徑>:源文件或者源目錄,這裡可以是通配符表達式,其通配符規則要滿足 Go 的 filepath.Match 規則。例如:

COPY hom* /mydir/COPY hom?.txt /mydir/<目標路徑>:容器內的指定路徑,該路徑不用事先建好,路徑不存在的話,會自動創建。

ADD

ADD 指令和 COPY 的使用格式一致(同樣需求下,官方推薦使用 COPY)。功能也類似,區別:

ADD 的優點在執行 <源文件> 為 tar 壓縮文件的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,會自動複製並解壓到 <目標路徑>。ADD 的缺點在不解壓的前提下,無法複製 tar 壓縮文件。會令鏡像構建緩存失效,從而可能會令鏡像構建變得比較緩慢。具體是否使用,可以根據是否需要自動解壓來決定。ADD hello /# 添加到根目錄並解壓ADD test.tar.gz / WORKDIR /rootADD hello test/ # /root/test/helloWORKDIR /rootCOPY hello test/最佳實踐

大部分情況,COPY優先於ADDADD比COPY多個解壓功能添加遠程文件/目錄請使用curl或者wget

6 ENV

ENV MYSQL VERSION 5.6# 設置常量RUN apt-get install -y mysql-server= "$(MYSQL_VERSION]" \ && rm -rf /var/lib/apt/lists/* # 引用常量最佳實踐

儘量使用,可增加項目的可維護性。

7 上下文路徑

指令最後一個 . 是上下文路徑

上下文路徑指 docker 在構建鏡像,有時候想要使用到本機的文件(比如複製),docker build 命令得知這個路徑後,會將路徑下的所有內容打包。由於 docker 的運行模式是 C/S。我們本機是 C,docker 引擎是 S。實際的構建過程是在 docker 引擎下完成的,所以這個時候無法用到我們本機的文件。這就需要把我們本機的指定目錄下的文件一起打包提供給 docker 引擎使用。如果未說明最後一個參數,那麼默認上下文路徑就是 Dockerfile 所在的位置。

上下文路徑下不要放無用的文件,因為會一起打包發送給 docker 引擎,如果文件過多會造成過程緩慢。

VOLUME & EXPOSE

存儲和網絡

CMD & ENTRYPOINT

實戰

項目源碼

python app.py

如何調試Dockerfile?比如執行到如下步驟時報錯

那就進入該臨時中轉鏡像即可docker run -it 4320f8b526bc /bin/bash進入後,直接查看 app,原來是個文件,並非路徑!檢查下 Dockerfile

注意那行意思是將 app.py 放到根目錄下並命名為 app,所以它不是個目錄。

之後再 build,run 即可。

參考

更多最佳實踐,盡在官方 Dockerfile 文件https://github.com/docker-libraryhttps://docs.docker.com/engine/reference/builder/

相關焦點

  • 編寫Dockerfile的最佳實踐
    希望讀者能夠對 docker 鏡像有一定的了解,閱讀這篇文章至少需要一下前提知識:了解 docker 的基礎概念,運行過容器熟悉 docker 鏡像的基礎知識,知道鏡像的分層結構最好是負責過某個 docker 鏡像的構建(使用 docker build 命令創建過自己的鏡像)
  • Dockerfile執行指令的詳細介紹與實踐
    註:這句話的意思相當於執行系統中ps -ef 兩個命令,CMD命令不一定會執行,如果在容器啟動的鏡像後面添加命令的話,它會替代Dockerfile中的CMD命令,例如:docker run xbcai.com/docker_run ls 我們在鏡像後面添加了ls命令,它會取代Dockerfile中的CMD4、RUN與CMD例子演示
  • 容器化的最佳實踐:阿里內部出品,Docker+K8S實戰文檔
    前言:阿里巴巴,作為國內網際網路公司的Top,算是業界的標杆,有阿里背景的程式設計師,也更具有權威性。作為程式設計師,都清楚阿里對於員工要求有多高,技術人員掌握的技術水平更是望塵莫及。所以,大廠程式設計師的很多經驗也都值得我們借鑑和學習,在一定程度上確實能夠幫助我們「走捷徑」。
  • Docker命令行參數和Dockerfile指令「收藏版」
    與容器相關的命令docker [CMD] [OPTS] [CONTAINER]以交互模式啟動容器 docker run -it richxsl/rhel7 bash cat /etc/redhat-release Red Hat
  • Java本地項目推送遠程docker鏡像最佳實踐
    集成操作步驟部署虛擬機centos開啟遠程docker控制本地項目添加Dockerfile文件本地項目配置docker-maven-plugin插件執行maven命令實現docker推送編寫以下Dockfile文件並放到對應項目工程下。
  • Docker入門-Dockerfile的使用
    在Dockerfile文件所在目錄執行:dockerbuild-tnginx:v3 .從命令的輸出結果中,我們可以清晰的看到鏡像的構建過程。在Step2中,RUN指令啟動了一個容器782d25b7c611,執行了所要示的命令,並最後提交了這一層ba38ff665f57,隨後刪除了所用到的這個容器782d25b7c611。
  • dockerfile使用詳解以及CMD、ENTRYPOINT的區別
    在進行docker部署的時候,我們就要知道如何製作一個鏡像文件,今天老顧就來介紹一下,怎麼製作一個鏡像文件?以及有些命令會引起我們的混亂。什麼是 Dockerfile?在Docker官方的Dockerfile最佳實踐文檔中要求,儘可能的使用COPY,因此COPY的語義很明確,就是複製文件而已,沒有必要使用ADD高級的命令ENV命令
  • 雲計算核心技術Docker教程:Dockerfile文件ARG命令詳解
    Dockerfile 中的 ARG 指令是定義參數名稱,以及定義其默認值。該默認值可以在構建命令 docker build 中用 --build-arg 參數名=值 來覆蓋。
  • Dockerfile官方文檔詳細介紹
    Docker可以通過閱讀Docker的指令來自動構建映像 Dockerfile。A Dockerfile是一個文本文檔,其中包含用戶可以在命令行上調用以組裝圖像的所有命令。使用docker build 用戶可以創建自動構建,該構建連續執行多個命令行指令。本頁描述您可以在中使用的命令Dockerfile。
  • 雲計算核心技術Docker教程:Dockerfile文件ENTRYPOINT命令詳解
    Dockerfile文件ENTRYPOINT指令和 CMD 一樣,都是在指定容器啟動程序及參數。ENTRYPOINT 在運行時也可以替代,不過比 CMD 要略顯繁瑣,需要通過 docker run 的參數 --entrypoint 來指定。
  • 雲計算核心技術Docker教程:Dockerfile文件CMD命令詳解
    Dockerfile文件ADD指令是用於指定默認的容器主進程的啟動命令。Docker 不是虛擬機,容器就是進程。既然是進程,那麼在啟動容器的時候,需要指定所運行的程序及參數。語法格式shell 格式:CMD 命令exec 格式:CMD ["可執行文件", "參數1", "參數2"...]參數列表格式:CMD ["參數1", "參數2"...]。在指定了 ENTRYPOINT 指令後,用 CMD 指定具體的參數。
  • Docker 日誌管理最佳實踐
    二、容器日誌2.1、常用查看日誌命令——docker logsdocker logs CONTAINER顯示當前運行的容器的日誌信息, UNIX 和 Linux 的命令有三種 輸入輸出,分別是 STDIN(標準輸入)、STDOUT(標準輸出)、STDERR
  • Docker安裝及命令整理
    Dockerfile什麼是DockerfileDockerfile是一個包含用於組合鏡像命令的文本文檔,docker通過讀取Dockerfile中的指令按步自動生成鏡像根據Dockerfile構建鏡像命令docker build -t 機構/鏡像名<
  • Docker 鏡像構建之 Dockerfile
    在 Dockerfile 中只能有一條 CMD 指令。如果設置了多條 CMD,只有最後一條 CMD 會生效。CMD ehco $JAVA_HOME  如果創建容器的時候指定了命令,則 CMD 命令會被替代。
  • 使用 Dockerfile 創建鏡像 | Docker 系列
    之前寫鏡像的時候說到創建鏡像最常用的方式是使用 dockerfile,這篇就來重點說一下,到底是怎麼使用 Dockerfile 來創建的。基本結構 2、維護者信息MAINTAINER docker_user docker_user@email.com34;deb http://archive.ubuntu.com/ubuntu/ raring main universe
  • docker系列 創建自己的docker及Dockerfile語法
    創建自己的docker測試伺服器已經安裝docker編寫測試工程主要代碼如下 DockerApplication : 服務類.3.執行pom.xml生成docker-0.0.1-SNAPSHOT.jar 將上面生成的docker-0.0.1-SNAPSHOT.jar複製到工作目錄如:/docker/simplebuild 4. 在工作目錄下,添加Dockerfile,內容如下.Dockerfile語法介紹本章後面介紹 5.
  • 雲計算核心技術Docker教程:Dockerfile文件EXPOSE命令詳解
    Dockerfile文件EXPOSE 指令是聲明運行時容器提供服務埠,這只是一個聲明,在運行時並不會因為這個聲明應用就會開啟這個埠的服務。在 Dockerfile 中寫入這樣的聲明有兩個好處,一個是幫助鏡像使用者理解這個鏡像服務的守護埠,以方便配置映射;另一個用處則是在運行時使用隨機埠映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的埠。
  • Dockerfile你值得擁有
    什麼是DockerfileDockerfile是一個用來將你的應用構建為docker鏡像的文本文件,文本中的內容是一條一條的指令,這些指令的集合在命令介紹先來看一個簡單的Dockerfile文件FROM hub.c.163.com/library/java:8VOLUME /tmpADD target/springboot-docker
  • 使用Dockerfile 創建鏡像|Docker 系列
    之前寫鏡像的時候說到創建鏡像最常用的方式是使用 Dockerfile,這篇就來重點說一下,到底是怎麼使用 Dockerfile 來創建的。基本結構# 1、第一行必須是 FROM 基礎鏡像信息FROM ubuntu# 2、維護者信息MAINTAINER docker_user docker_user@email.com
  • Dockerfile配合docker-compose實現環境自動化
    docker-file,docker-compose本文介紹了dockerfile,docker-compose的知識點,全文(2900)個字,閱讀大概需要(15)分鐘!簡介:什麼是DockerfileDockerfile 是一個用來構建鏡像的文本文件,文本內容包含了一條條構建鏡像所需的指令和說明。FROM 和 RUN 指令的作用FROM:定製的鏡像都是基於 FROM 的鏡像,這裡的 nginx 就是定製需要的基礎鏡像。後續的操作都是基於 nginx。RUN:用於執行後面跟著的命令行命令。