01 DockerFile介紹:
Dockerfile是由一系列命令和參數構成的腳本,一個Dockerfile裡面包含了構建整個image的完整命令。Docker通過docker build執行Dockerfile中的一系列命令自動構建image。
實例:
這裡我們仍然選擇我們上一篇使用的在centos基礎上定製我們自己的鏡像為本章的代碼實例,代碼如下:
之後再通過docker build 命令編譯該DockerFile便可以得到一個屬於自己的鏡像了。
運行該鏡像會發現vim和net-tools在我們新的容器中已經可以正常使用了。
接下來呢,我們將從FROM命令開始逐行介紹,最終完成對DockerFile常用命令的瞭解和掌握。
Docker學習思維腦圖,有需要的可以私信 “學習” 免費領取!!
Docker學習思維腦圖
02 常用命令:
(1)FROM命令:
既然我們是在原有的centos鏡像的基礎上做定製,那麼我們的新鏡像也一定是需要以centos這個鏡像為基礎的,而FROM命令則代表了這個意思,在DockerFile中,基礎鏡像是必須指定的,FROM指令的作用就是指定基礎鏡像,因此一個DockerFile中,FROM是必備的指令,而且就像java,python的import關鍵字一樣,在DockerFile中,FROM指令必須放在第一條指令的位置
當然,這個時候可能有朋友會問了,我要是不想在其他的鏡像上定製鏡像怎麼辦呢,沒問題啊,Docker 提供了scratch 這個虛擬鏡像,如果你選擇 FROM scratch 的話,則意味著你不以任何鏡像為基礎,接下來所寫的指令將作為鏡像的第一層開始存在,當然,在某些情況下,比如linux下靜態編譯的程序,運行的時候不需要操作系統提供運行時的支持,這個時候FROM scratch 是沒有問題的,反而會大幅降低我們的鏡像體積。
(2)ENV指令
功能:設置環境變量
同樣的,DockerFile也提供了兩種格式:
ENV key valueENV key1=value1 key2=value2這個指令很簡單,就是設置環境變量而已,無論是後面的其它指令,如 RUN, 還是運行時的應用,都可以直接使用這裡定義的環境變量。
可以看到我們示例中使用ENV設置mypath變量之後,在下一行WORKDIR則使用到了mypath這個變量
(3)WORKDIR 指令:
功能,指定工作目錄
格式為:WORKDIR 工作目錄路徑,如果這個目錄不存在的話,WORKDIR則會幫助我們創建這個目錄。
設置過工作目錄之後,當我們啟動容器,會直接進入該工作目錄
(4)RUN命令:
RUN 指令是用來執行命令行命令的。由於命令行的強大能力,RUN 指令也是在定製鏡像時是較為常用的指令之一。
RUN命令的格式一共有兩種,分別是:
Shell 格式 RUN 命令,就像直接在命令行中輸入命令一樣,比如RUN yum -y install vim就是使用的這種格式exec 格式 RUN["可執行文件","參數1","參數2"],感覺就像調用函數一樣就像我們在上一篇文章中說過的那樣,DockerFile中每一條指令都會建立一層,比如我們上面執行過下面這條命令
執行結束之後,則調用commit提交這一層的修改,使之構成一個新的鏡像,怎麼樣,是不是豁然開朗了呢。
並沒有
那好吧
同樣的,Dockerfile 支持 Shell 類的行尾添加 \\ 的命令換行方式,以 及行首 # 進行註釋的格式。良好的格式,比如換行、縮進、註釋等,會讓維護、排障更為容易,這是一個比較好的習慣。
提示:
如果使用apt方式安裝的話,最後不要忘記清理掉額外產生的apt緩存文件,如果不清理的話會讓我們的鏡像顯得非常臃腫。因為DockerFile生成一層新的鏡像的時候,並不會刪除上一層鏡像所殘留的文件。
(5)EXPOSE指令:
格式: EXPOSE 端口1 端口2
EXPOSE 指令是聲明運行時容器提供服務端口,這當然只是一個聲明,在運行時並不會因為這個聲明應用就會開啟這個端口的服務。這樣聲明主要是為了方便後期我們配置端口映射。
(6)CMD指令:
之前介紹容器的時候曾經說過,Docker 不是虛擬機,容器就是進程。既然是進程,那麼在啟動容器的時候,需要指定所運行的程序及參數。CMD 指令就是用於指定默認的容器主進程的啟動命令的。
同樣的,DockerFile也為我們提供了兩種格式來使用CMD命令:
shell 格式:CMD 命令exec 格式:CMD ["可執行文件", "參數 1", "參數 2"...]示例中,我們使用的是第一種:
這條指令帶來的效果就是,當我們通過run -it 啟動命令的時候,容器會自動執行/bin/bash,centos默認也是CMD /bin/bash,所以當我們運行centos鏡像的時候,會自動進入bash環境裡面。
當然,我們也可以通過運行時指定命令的方式來體換默認的命令,比如:
這樣當我們運行鏡像的時候,cat /etc/os-release就會替代默認的CMD /bin/bash 輸出系統的版本信息了。
如果使用 shell 格式的話, 實際的命令會被包裝為 sh -c 的參數的形式進行執行。
比如:
在實際執行中,會將其變更為
當然還有很多初學者特別容易犯的問題,就是去啟動後臺服務,比如:
這樣子去用,會發現容器運行了一會就自動退出了。
所以,?????
我們之前不止一次的提醒過,容器不是虛擬機,容器就是進程,容器內的應用都應該以前臺運行,而不是像虛擬機,物理機那樣去運行後臺服務,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。
怎麼理解呢?想想偶像劇,容器是女主角,主進程是男主角
你走了,我也不活了(撕心裂肺大哭),大概就是這麼個意思。
正如我們前面所提出的,實際上CMD service nginx start 最終會被理解為:
在這裡,我們主進程實際就是sh,當我們service nginx start執行完畢之後,那麼sh自然就會退出了,主進程退出,容器自然就會相應的停止。爭取的做法是直接執行nginx可執行文件,並且聲明以前臺的形式運行:
到這裡,我們示例中所涉及到的命令已經講完了,當然,這並不夠,Docker中仍然有很多命令是我們使用比較頻繁的,下面我們的部分作為補充,講一下其他常用的DockerFile命令。
(7)COPY 命令:
功能:複製文件
Docker依舊提供了兩種格式供我們選擇:
COPY [--chown=:] ... COPY [--chown=:] ["",... ""]到這裡大家其實會發現,Docker提供的兩種格式其實都是差不多的用法,一種類似於命令行,一種則類似於函數調用。
第一種例如(將package.json拷貝到/usr/src/app/目錄下):
其次,目標路徑 可以是容器內的絕對路徑,也可以是相對於工作目錄的相對路徑 ,工作目錄可以用 WORKDIR 指令來指定,如果需要改變文件所屬的用戶或者用戶組,可以加上--chown 選項。
需要注意的是,使用 COPY 指 令,源文件的各種元數據都會保留。比如讀、寫、執行權限、文件變更時間等。這 個特性對於鏡像定製很有用。
(8)ADD命令:
ADD命令可以理解為COPY命令的高級版,格式和用法與COPY幾乎一致,ADD在COPY的基礎上增加了一些功能,比如源路徑可以是一個URL鏈接,當你這麼用的時候,Docker會嘗試著先將該URL代表的文件下載下來,然後複製到目標目錄上去,其他的則是在COPY的基礎上增加了解壓縮之類的操作,碼字碼的手疼,需要了解的朋友可以去官網查看相關的文檔,這裡我就不延申了。
(9)VOLUME 定義匿名卷:
在上一篇中,我們有講容器卷這個概念,為了防止運行時用戶忘記 將動態文件所保存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些 目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運 行,不會向容器存儲層寫入大量數據。
例如:
運行時通過-v參數即可以覆蓋默認的匿名卷設置。
(10)USER 命令:
功能:指定當前用戶
格式:USER 用戶名:用戶組
USER 指令和 WORKDIR 相似,都是改變環境狀態並影響以後的層。WORKDIR 是改變工作目錄,USER 則是改變之後層的執行 RUN, CMD 以及 ENTRYPOINT 這類命令的身份。當然,和 WORKDIR 一樣,USER 只是幫助你切換到指定用戶。
當然這個大前提是,你的User用戶是事先存在好的。
原文鏈接:https://juejin.im/post/5dafa60ff265da5b62535bcf