Linux中國

Docker 快速入門之 Dockerfile

之前的文章中我們提到可以通過容器創建一個我們自定義過的鏡像,那麼我們是否可以直接通過基礎的鏡像直接自定義鏡像呢?答案當然是可以的,在 Docker 中我們可以從名為 Dockerfile 的文件中讀取指令並且自動構建鏡像。在本文中,將介紹 Dockerfile 的基本語法以及基本知識。

1、Dockerfile 是什麼?

Dockerfile 其實是一份文本文檔,裡面包含了用戶可以用來操作鏡像的一些指令。通過順序執行這些指令,最後得到一個自定義的鏡像,這有點類似於我們的 shell 腳本。

2、Dockerfile 示例

接下來先看一個 Dockerfile 示例:

FROM centos
LABEL maintainer="Locez <locez@locez.com>"
ENV TEST="This is a test env"
COPY nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum update -y && 
        yum install -y nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY index.html /usr/share/nginx/html/index.html
COPY index_files/ /usr/share/nginx/html/index_files/
EXPOSE 80
CMD ["/usr/sbin/nginx","-g","daemon off;"]

在上面我們可以看到 Dockerfile 中的一些指令,通過名稱我們也可以猜到這些指令大概是幹嘛的,其中有一些對文件的操作,因此我們先來看看用於存放 Dockerfile 的這個目錄的目錄結構:

# tree .
.
├── Dockerfile
├── index_files
│   ├── 145049z4og8xyjhx4xy8go.jpg
│   ├── 222746e5vh38d7ey3leyps.jpg
│   ├── 88x31.png
│   ├── archlinux-splash.png
│   ├── bdshare.css
│   ├── Best-Linux-Markdown-Editors.png
│   ├── core.js
│   ├── docker-icon.jpg
│   ├── hadoop-pic1.png
│   ├── jquery_002.js
│   ├── jquery.css
│   ├── jquery.js
│   ├── MathJax.js
│   ├── pic.gif
│   ├── raspberrypiraspberry-pi-logo.jpg
│   ├── script.js
│   ├── scrollup.png
│   ├── share.js
│   ├── style.css
│   └── z_stat.js
├── index.html
├── nginx.conf
└── nginx.repo

1 directory, 24 files

構建鏡像

在當前目錄下執行以下命令構建鏡像:

# docker build -t locez/nginx .
Sending build context to Docker daemon 1.851 MB
Step 1/10 : FROM centos
 ---> 196e0ce0c9fb
Step 2/10 : LABEL maintainer "Locez <locez@locez.com>"
 ---> Using cache
 ---> 9bba3042bcdb
Step 3/10 : ENV TEST "This is a test env"
 ---> Using cache
 ---> c0ffe95ea0c5
Step 4/10 : COPY nginx.repo /etc/yum.repos.d/nginx.repo
 ---> Using cache
 ---> bb6ee4c30d56
Step 5/10 : RUN yum update -y &&        yum install -y nginx
 ---> Using cache
 ---> 6d46b41099c3
Step 6/10 : COPY nginx.conf /etc/nginx/nginx.conf
 ---> Using cache
 ---> cfe908390aae
Step 7/10 : COPY index.html /usr/share/nginx/html/index.html
 ---> Using cache
 ---> 21729476079d
Step 8/10 : COPY index_files/ /usr/share/nginx/html/index_files/
 ---> Using cache
 ---> 662f06ec7b46
Step 9/10 : EXPOSE 80
 ---> Using cache
 ---> 30db5a889d0a
Step 10/10 : CMD /usr/sbin/nginx -g daemon off;
 ---> Using cache
 ---> d29b9d4036d2
Successfully built d29b9d4036d2

然後用該鏡像啟動容器

# docker run -d -it --rm --name test-nginx -p 8080:80 locez/nginx
e06fd991ca1b202e08cf1578f8046355fcbba10dd9a90e11d43282f3a1e36d29

用瀏覽器訪問 http://localhost:8080/ 即可看到部署的內容。

3 Dockerfile 指令解釋

Dockerfile 支持 FROMRUNCMDLABELEXPOSEENVADDCOPYENTRYPOINTVOLUMEUSERWORKDIRARGONBUILDSHELL 等指令,這裡只選擇常用的幾個進行講解,可結合上面的示例進行理解。其它的請自行查閱官方文檔。

3.1 FROM

FROM 指令用於指定要操作的基礎鏡像,因為在我們構建我們自己的鏡像的時候需要一個基礎鏡像。 語法:

FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]

其中 [AS <name>] 為指定一個名稱,在一個 Dockerfile 中多次使用 FROM 時如有需要,可用 COPY --from=<name|index> 語法進行複製。

3.2 RUN

RUN 指令用於執行命令,並且是在新的一層上執行,並把執行後的結果提交,也就是生成新的一層。基於這個問題,我們在使用 RUN 指令時應該儘可能的把要執行的命令一次寫完,以減少最後生成的鏡像的層數。 語法:

RUN <command>
RUN ["executable", "param1", "param2"]

3.3 CMD

CMD 指令用於給容器啟動時指定一個用於執行的命令,例如上例中的 nginx 啟動命令。 語法:

CMD ["executable","param1","param2"]
CMD ["param1","param2"] ### 用於給 ENTRYPOINT 指令提供默認參數
CMD command param1 param2

3.4 LABEL

LABEL 指令用於為鏡像指定標籤,可用 docker inspect 命令查看。可用來代替被捨棄的 MAINTAINER 命令。 語法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

3.5 EXPOSE

EXPOSE 指令用於告訴 Docker 容器監聽的特殊埠,但是此時埠還沒有暴露給 host ,只有當在運行一個容器顯式用參數 -p 或者 -P 的時候才會暴露埠。 語法:

EXPOSE <port> [<port>/<protocol>...]

3.6 ENV

ENV 指令用於設定環境變數。 語法:

ENV <key> <value>
ENV <key>=<value> ...

3.7 ADD

ADD 指令用於複製新文件,目錄,遠程文件到容器中。其中 <src> 可以為文件,目錄,URL,若為可解壓文件,在複製後會解壓。 語法:

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

3.8 COPY

COPY 指令與 ADD 指令非常相似,但 COPY 比較直觀且簡單,它只支持本地的文件以及目錄的複製,不像 ADD 指令可以遠程獲取文件並解壓。 語法:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

3.9 ENTRYPOINT

ENTRYPOINT 指令也跟 CMD 指令相似,用於指定容器啟動時執行的命令。當使用 ENTRYPOINT 指令時,可用 CMD 命令配合,這樣在啟動容器時,可以對 CMD 指令寫入的參數進行覆蓋。 語法:

ENTRYPOINT ["executable", "param1", "param2"]

例子:

ENTRYPOINT ["top","-b"]
CMD ["-c"]

上面的 -c 參數可以在啟動時覆蓋 docker run -it --rm --name test top -H。 如果要覆蓋 ENTRYPOINT 指令則用 --entrypoint 參數啟動容器。

3.10 VOLUME

VOLUME 指令用於為容器創建一個掛載點,這個掛載點可以用來掛載 本地文件/文件夾 也可以用來掛載 數據卷。其中若在啟動一個新容器時沒有指定掛載目錄,則會自動創建一個數據卷,當容器被銷毀時,數據卷如果沒有被其它容器引用則會被刪除。 語法:

VOLUME ["/data1","/data2"]

3.11 USER

USER 指令用於設置執行 RUN, CMD, ENTRYPOINT 等指令的用戶以及用戶組。默認為 root 用戶。 語法:

USER <user>[:<group>]

3.12 WORKDIR

WORKDIR 指令用於設置 RUN, CMD, ENTRYPOINT, COPY, ADD 等指令的工作目錄。 語法:

WORKDIR /path/to/workdir

4 總結

本文從一個具體的例子出發,講述了如何利用 Dockerfile 構建鏡像,然後解釋了 Dockerfile 文件中的指令的語法,有關更多內容可訪問官方文檔。

5 參考資料


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國