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 支持 FROM
、 RUN
、 CMD
、 LABEL
、 EXPOSE
、 ENV
、 ADD
、 COPY
、 ENTRYPOINT
、 VOLUME
、 USER
、 WORKDIR
、 ARG
、 ONBUILD
、 SHELL
等指令,這裡只選擇常用的幾個進行講解,可結合上面的示例進行理解。其它的請自行查閱官方文檔。
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