【Docker系列教程之五】如何構建Dockerfile
在上一篇文章中,我們講述了 Dockerfile
的組成以及指令的編寫過程,在本篇文章中詳細講解如何構建 Dockerfile
。
Dockerfile常用的指令
那麼在講如何構建 Dockerfile
之前,我們回顧一下上一篇的編寫過程:
-
1、從
DockerHub
上pull
下指定的基礎映象 -
2、顯示維護者的資訊
-
3、
copy
當前目錄到容器中的指定目錄下 複製本地主機的<src>
(Dockerfile
所在目錄的相對路徑)到容器裡<dest>
-
4、指定工作路徑
-
5、安裝依賴包
-
6、暴露埠
-
7、啟動容器
我們已經差不多知道了 Dockerfile
的組成以及指令的編寫過程,我們再來理解一下這些常用命令就會得心應手了。
由於 Dockerfile
中所有的命令都是以下格式: INSTRUCTION argument
,指令 (INSTRUCTION)
不分大小寫,但是推薦大寫,和sql語句是不是很相似呢?下面我們正式來講解一下這些指令集吧。
FROM
FROM
是用於指定基礎的 images
,一般格式為 FROM<image>
or FORM<image>:<tag>
,所有的 Dockerfile
都用該以 FROM
開頭, FROM
命令指明 Dockerfile
所建立的映象檔案以什麼映象為基礎, FROM
以後的所有指令都會在 FROM
的基礎上進行建立映象。可以在同一個 Dockerfile
中多次使用 FROM
命令用於建立多個映象。比如我們要指定 python2.7
的基礎映象,我們可以像如下寫法一樣:
-
FROM python:2.7
MAINTAINER
MAINTAINER 是用於指定映象建立者和聯絡方式,一般格式為 MAINTAINER<name>
。這裡我設定成我的 ID
和郵箱:
-
MAINTAINER Angel_Kitty <[email protected].com>
COPY
COPY
是用於複製本地主機的 <src>
(為 Dockerfile 所在目錄的相對路徑)到容器中的 <dest>
。
當使用本地目錄為源目錄時,推薦使用 COPY
。一般格式為 COPY<src><dest>
。例如我們要拷貝當前目錄到容器中的 /app
目錄下,我們可以這樣操作:
-
COPY . /app
WORKDIR
WORKDIR
用於配合 RUN
, CMD
, ENTRYPOINT
命令設定當前工作路徑。可以設定多次,如果是相對路徑,則相對前一個 WORKDIR
命令。預設路徑為 /
。一般格式為 WORKDIR/path/to/work/dir
。例如我們設定 /app
路徑,我們可以進行如下操作:
-
WORKDIR /app
RUN
RUN
用於容器內部執行命令。每個 RUN
命令相當於在原有的映象基礎上添加了一個改動層,原有的映象不會有變化。一般格式為 RUN<command>
。例如我們要安裝 python
依賴包,我們做法如下:
RUN pip install -r requirements.txt
EXPOSE
EXPOSE
命令用來指定對外開放的埠。一般格式為 EXPOSE<port>[<port>...]
例如上面那個例子,開放5000埠:
-
EXPOSE 5000
ENTRYPOINT
ENTRYPOINT
可以讓你的容器表現得像一個可執行程式一樣。一個 Dockerfile
中只能有一個 ENTRYPOINT
,如果有多個,則最後一個生效。
ENTRYPOINT
命令也有兩種格式:
ENTRYPOINT["executable","param1","param2"] :推薦使用的 exec形式 ENTRYPOINT command param1 param2 : shell 形式
例如下面這個,我們要將 python
映象變成可執行的程式,我們可以這樣去做:
-
ENTRYPOINT ["python"]
CMD
CMD
命令用於啟動容器時預設執行的命令, CMD
命令可以包含可執行檔案,也可以不包含可執行檔案。不包含可執行檔案的情況下就要用 ENTRYPOINT
指定一個,然後 CMD
命令的引數就會作為 ENTRYPOINT
的引數。
CMD
命令有三種格式:
CMD["executable","param1","param2"]:推薦使用的 exec 形式。 CMD["param1","param2"]:無可執行程式形式 CMD command param1 param2:shell 形式。
一個 Dockerfile
中只能有一個 CMD
,如果有多個,則最後一個生效。而 CMD
的 shell
形式預設呼叫 /bin/sh-c
執行命令。
CMD
命令會被 Docker
命令列傳入的引數覆蓋: docker run busybox/bin/echoHello
Docker
會把 CMD
裡的命令覆蓋。
例如我們要啟動 /app
,我們可以用如下命令實現:
-
CMD ["app.py"]
當然還有一些其他的命令,我們在用到的時候再去一一講解一下。
構建Dockerfile
我們大體已經把Dockerfile的寫法講述完畢,我們可以自己動手寫一個例子:
~~~shell mkdir staticweb cd staticweb touch Dockerfile 然後 vi Dockerfile 開始編輯該檔案 輸入 i 開始編輯
以下是我們構建的Dockerfile內容
FROM nginx MAINTAINER Angel_Kitty <[email protected]> RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html ```````
編輯完後 按 esc 退出編輯 然後 :wq 寫入 退出 ~~~
我們在 Dockerfile
檔案所在目錄執行:
-
docker build -t angelkitty/nginx_web:v1 .
我們解釋一下, -t
是為新映象設定倉庫和名稱,其中 angelkitty
為倉庫名, nginx_web
為映象名, :v1
為標籤(不新增為預設 latest
)
我們構建完成之後,使用 docker images
命令檢視所有映象,如果存在 REPOSITORY
為 nginx
和 TAG
是 v1
的資訊,就表示構建成功。
接下來使用 docker run
命令來啟動容器
docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1
這條命令會用 nginx 映象啟動一個容器,命名為 nginx_web
,並且映射了 8080 埠,這樣我們可以用瀏覽器去訪問這個 nginx
伺服器: http://localhost:8080/
或者 http://本機的IP地址:8080/,頁面返回資訊:
這樣一個簡單使用 Dockerfile
構建映象,執行容器的示例就完成了!
總結
到此為止,Docker的基礎部分已經說的差不多了,在後續的文章中,我會帶大家瞭解一些Docker底層實現的原理以及Linux核心部分。由於Docker是用Golang語言開發的,這時候我們可能需要Golang語言的基礎,不過不必擔心,只要你有C語言的基礎就行,我們在後續的文章中講解一點Golang語言相關的基礎知識。