Docker 實戰:編寫 Dockerfile

一、編譯鏡像

?

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

?

1. 編譯鏡像

????Dockerfile類似于Makfile,用戶使用docker build就可以編譯鏡像,使用該命令可以設置編譯鏡像時使用的CPU數量、內存大小、文件路徑等

語法:docker build [OPTIONS] PATH| URL| -?
常見選項:?
??????????-t 設置鏡像的名稱和TAG,格式為name:tag?
??????????-f Dockerfile的名稱,默認為PATH/Dockerfile?
例子:docker build -f ~/php.Dockerfile .?
注意:PATH是編譯鏡像使用的工作目錄,Docker Daemon在編譯開始時,會掃描PATH中的所有文件,可以在編譯目錄中加入.dockerignore過濾不需要的文件

????Docker Daemon從Dockerfile中順序讀取指令,生成一個臨時容器,在容器中執行指令,容器編譯成功后會提交作為鏡像層加入最終鏡像,為了加快編譯過程,Docker Daemon采用了緩存機制,如果在緩存中找到了需要的中間鏡像則直接使用該鏡像而不生成臨時容器(編譯時可以使用選項–no-cache選擇不使用緩存)

2. dockerignore文件

????編譯開始前,Docker Daemon會讀取編譯目錄中的.dockerignore文件,忽略其中的文件和目錄,在其中可以使用通配符(?代表一個字符,*代表零個或任意個字符),使用通配符時,總會出現那么幾個例外,這時可以使用!+文件名,Docker Daemon會讀取!后面的文件

*/temp* 忽略PATH路徑下一級子目錄中以temp開頭的文件和目錄,如PAHT/A/temp.txt
*/*/temp* 忽略PATH路徑下二級子目錄中以temp開頭的文件和目錄,如PATH/A/B/temp.txt
*.md
!README.md 忽略所有md文件,除了README.md

二、Dockerfile指令詳解

????Dockerfile由多條指令組成,每條指令在編譯鏡像時執行相應的程序完成某些功能,由指令+參數組成,以逗號分隔,#作為注釋起始符,雖說指令不區分大小寫,但是一般指令使用大些,參數使用小寫

這里寫圖片描述

指令:FROM?
功能描述:設置基礎鏡像?
語法:FROM < image>[:< tag> | @< digest>]?
提示:鏡像都是從一個基礎鏡像(操作系統或其他鏡像)生成,可以在一個Dockerfile中添加多條FROM指令,一次生成多個鏡像?
注意:如果忽略tag選項,會使用latest鏡像


指令:MAINTAINER?
功能描述:設置鏡像作者?
語法:MAINTAINER < name>


指令:RUN?
功能描述:?
語法:RUN < command>?
??????????RUN [“executable”,”param1”,”param2”]?
提示:RUN指令會生成容器,在容器中執行腳本,容器使用當前鏡像,腳本指令完成后,Docker Daemon會將該容器提交為一個中間鏡像,供后面的指令使用?
補充:RUN指令第一種方式為shell方式,使用/bin/sh -c < command>運行腳本,可以在其中使用\將腳本分為多行?
??????????RUN指令第二種方式為exec方式,鏡像中沒有/bin/sh或者要使用其他shell時使用該方式,其不會調用shell命令?
例子:RUN source?$HOME/.bashrc;\?
??????????echo $HOME

??????????RUN [“/bin/bash”,”-c”,”echo hello”]

??????????RUN [“sh”,”-c”,”echo”,”$HOME”] 使用第二種方式調用shell讀取環境變量


指令:CMD?
功能描述:設置容器的啟動命令?
語法:CMD [“executable”,”param1”,”param2”]?
??????????CMD [“param1”,”param2”]?
??????????CMD < command>?
提示:CMD第一種、第三種方式和RUN類似,第二種方式為ENTRYPOINT參數方式,為entrypoint提供參數列表?
注意:Dockerfile中只能有一條CMD命令,如果寫了多條則最后一條生效


指令:LABEL?
功能描述:設置鏡像的標簽?
延伸:鏡像標簽可以通過docker inspect查看?
格式:LABEL < key>=< value> < key>=< value> …?
提示:不同標簽之間通過空格隔開?
注意:每條指令都會生成一個鏡像層,Docker中鏡像最多只能有127層,如果超出Docker Daemon就會報錯,如LABEL ..=.. <假裝這里有個換行> LABEL ..=..合在一起用空格分隔就可以減少鏡像層數量,同樣,可以使用連接符\將腳本分為多行?
??????????鏡像會繼承基礎鏡像中的標簽,如果存在同名標簽則會覆蓋


指令:EXPOSE?
功能描述:設置鏡像暴露端口,記錄容器啟動時監聽哪些端口?
語法:EXPOSE < port> < port> …?
延伸:鏡像暴露端口可以通過docker inspect查看?
提示:容器啟動時,Docker Daemon會掃描鏡像中暴露的端口,如果加入-P參數,Docker Daemon會把鏡像中所有暴露端口導出,并為每個暴露端口分配一個隨機的主機端口(暴露端口是容器監聽端口,主機端口為外部訪問容器的端口)?
注意:EXPOSE只設置暴露端口并不導出端口,只有啟動容器時使用-P/-p才導出端口,這個時候才能通過外部訪問容器提供的服務


指令:ENV?
功能描述:設置鏡像中的環境變量?
語法:ENV < key>=< value>…|< key> < value>?
注意:環境變量在整個編譯周期都有效,第一種方式可設置多個環境變量,第二種方式只設置一個環境變量?
提示:通過${變量名}或者?$變量名使用變量,使用方式${變量名}時可以用${變量名:-default}?${變量名:+cover}設定默認值或者覆蓋值?
??????????ENV設置的變量值在整個編譯過程中總是保持不變的


指令:ADD?
功能描述:復制文件到鏡像中?
語法:ADD < src>… < dest>|[“< src>”,… “< dest>”]?
注意:當路徑中有空格時,需要使用第二種方式?
??????????當src為文件或目錄時,Docker Daemon會從編譯目錄尋找這些文件或目錄,而dest為鏡像中的絕對路徑或者相對于WORKDIR的路徑?
提示:src為目錄時,復制目錄中所有內容,包括文件系統的元數據,但不包括目錄本身?
??????????src為壓縮文件,并且壓縮方式為gzip,bzip2或xz時,指令會將其解壓為目錄?
??????????如果src為文件,則復制文件和元數據?
??????????如果dest不存在,指令會自動創建dest和缺失的上級目錄


指令:COPY?
功能描述:復制文件到鏡像中?
語法:COPY < src>… < dest>|[“< src>”,… “< dest>”]?
提示:指令邏輯和ADD十分相似,同樣Docker Daemon會從編譯目錄尋找文件或目錄,dest為鏡像中的絕對路徑或者相對于WORKDIR的路徑


指令:ENTRYPOINT?
功能描述:設置容器的入口程序?
語法:ENTRYPOINT [“executable”,”param1”,”param2”]?
??????????ENTRYPOINT command param1 param2(shell方式)?
提示:入口程序是容器啟動時執行的程序,docker run中最后的命令將作為參數傳遞給入口程序?
??????????入口程序有兩種格式:exec、shell,其中shell使用/bin/sh -c運行入口程序,此時入口程序不能接收信號量?
??????????當Dockerfile有多條ENTRYPOINT時只有最后的ENTRYPOINT指令生效?
??????????如果使用腳本作為入口程序,需要保證腳本的最后一個程序能夠接收信號量,可以在腳本最后使用exec或gosu啟動傳入腳本的命令?
注意:通過shell方式啟動入口程序時,會忽略CMD指令和docker run中的參數?
??????????為了保證容器能夠接受docker stop發送的信號量,需要通過exec啟動程序;如果沒有加入exec命令,則在啟動容器時容器會出現兩個進程,并且使用docker stop命令容器無法正常退出(無法接受SIGTERM信號),超時后docker stop發送SIGKILL,強制停止容器?
例子:FROM ubuntu <換行> ENTRYPOINT exec top -b


指令:VOLUME?
功能描述:設置容器的掛載點?
語法:VOLUME [“/data”]?
??????????VOLUME /data1 /data2?
提示:啟動容器時,Docker Daemon會新建掛載點,并用鏡像中的數據初始化掛載點,可以將主機目錄或數據卷容器掛載到這些掛載點


指令:USER?
功能描述:設置RUN CMD ENTRYPOINT的用戶名或UID?
語法:USER < name>


指令:WORKDIR?
功能描述:設置RUN CMD ENTRYPOINT ADD COPY指令的工作目錄?
語法:WORKDIR < Path>?
提示:如果工作目錄不存在,則Docker Daemon會自動創建?
??????????Dockerfile中多個地方都可以調用WORKDIR,如果后面跟的是相對位置,則會跟在上條WORKDIR指定路徑后(如WORKDIR /A ??WORKDIR B ??WORKDIR C,最終路徑為/A/B/C)


指令:ARG?
功能描述:設置編譯變量?
語法:ARG < name>[=< defaultValue>]?
注意:ARG從定義它的地方開始生效而不是調用的地方,在ARG之前調用編譯變量總為空,在編譯鏡像時,可以通過docker build –build-arg < var>=< value>設置變量,如果var沒有通過ARG定義則Daemon會報錯?
??????????可以使用ENV或ARG設置RUN使用的變量,如果同名則ENV定義的值會覆蓋ARG定義的值,與ENV不同,ARG的變量值在編譯過程中是可變的,會對比使用編譯緩存造成影響(ARG值不同則編譯過程也不同)?
例子:ARG CONT_IMAG_VER <換行> RUN echo $CONT_IMG_VER?
??????????ARG CONT_IMAG_VER <換行> RUN echo hello?
??????????當編譯時給ARG變量賦值hello,則兩個Dockerfile可以使用相同的中間鏡像,如果不為hello,則不能使用同一個中間鏡像


指令:ONBUILD?
功能描述:設置自徑想的編譯鉤子指令?
語法:ONBUILD [INSTRUCTION]?
提示:從該鏡像生成子鏡像,在子鏡像的編譯過程中,首先會執行父鏡像中的ONBUILD指令,所有編譯指令都可以成為鉤子指令


指令:STOPSIGNAL?
功能描述:設置容器退出時,Docker Daemon向容器發送的信號量?
語法:STOPSIGNAL signal?
提示:信號量可以是數字或者信號量的名字,如9或者SIGKILL,信號量的數字說明在Linux系統管理中有簡單介紹


補充:ONBUILD流程

  • 編譯時,讀取所有ONBUILD鏡像并記錄下來,在當前編譯過程中不執行指令
  • 生成鏡像時將所有ONBUILD指令記錄在鏡像的配置文件OnBuild關鍵字中
  • 子鏡像在執行FROM指令時會讀取基礎鏡像中的ONBUILD指令并順序執行,如果執行過程中失敗則編譯中斷;當所有ONBUILD執行成功后開始執行子鏡像中的指令
  • 子鏡像不會繼承基礎鏡像中的ONBUILD指令

補充:CMD ENTRYPOINT和RUN的區別

????RUN指令是設置編譯鏡像時執行的腳本和程序,鏡像編譯完成后,RUN指令的生命周期結束

????容器啟動時,可以通過CMD和ENTRYPOINT設置啟動項,其中CMD叫做容器默認啟動命令,如果在docker run命令末尾添加command,則會替換鏡像中CMD設置的啟動程序;ENRTYPOINT叫做入口程序,不能被docker run命令末尾的command替換,而是將command當作字符串,傳遞給ENTRYPOINT作為參數

FROM ubuntu
ENTRYPOINT ["ps"]//通過命令docker run --rm test啟動容器,打印ps的輸出
//通過命令docker run --rm test -ef啟動容器,打印ps -ef的輸出

????在docker run中,可以通過–entrypoint替換鏡像中的入口程序,在Dockerfile中,應該至少有一條CMD或者ENTRYPOINT指令,如果同時定義了CMD和ENTRYPOINT則CMD會作為參數傳遞給ENTRYPOINT

FROM ubuntu
ENTRYPOINT ["ps"]
CMD ["-ef"]//通過命令docker run --rm test啟動容器,打印ps -ef的輸出

?

?轉自:https://blog.csdn.net/qq_29999343/article/details/78318397

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448819.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448819.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448819.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

dubbo-環境搭建,實現一個簡單地dubbo實例(附github地址)

一、建立maven模塊和provider、consumer、service子模塊&#xff0c;其中service是開發接口的模塊 建立一個maven模塊&#xff0c;不選擇樣板&#xff0c;直接next知道完成&#xff0c;建立三個子模塊,建立完后發現各個模塊的java目錄不是源目錄 右鍵——>make Directory as…

static 二次理解

當api底層用到static修飾的話&#xff0c;因為是類的&#xff0c;此容器中只有一份轉載于:https://blog.51cto.com/jiaxiaoxu/2394844

AMD 5XXX 系列顯卡的 peak bandwidth計算

在ATI Stream Computing Programming Guide中&#xff0c;例舉了AMD 5系列顯卡的參數信息。 我比較關注其中Peak bandwidths的計算&#xff0c;以便在opencl程序測試bandwidth利用率。 下面&#xff0c;我以5870為例&#xff0c;探討一下如何計算得到這些結果&#xff1a; L1 c…

Docker : Dockerfile 定制鏡像

使用 Dockerfile 定制鏡像 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 鏡像的定制實際上就是定制每一層所添加的配置、文件。如果我們可以把每一層修改、安裝、構建、操作的命令都寫…

動態規劃 最長上升子序列

題意&#xff1a;給出一個序列&#xff0c;求它的最長上升子序列的長度 題目鏈接&#xff1a;https://ac.nowcoder.com/acm/problem/26156 輸入:n代表長度&#xff0c;然后是一個字符串 分析&#xff1a;用dp[i]表示長度為i1的上升子序列末尾元素的最小值&#xff08;一開始初始…

解說redis中如何實現高可用

redis中為了實現高可用&#xff08;High Availability&#xff0c;簡稱HA&#xff09;&#xff0c;采用了如下兩個方式&#xff1a;主從復制數據。采用哨兵監控數據節點的運行情況&#xff0c;一旦主節點出現問題由從節點頂上繼續進行服務。主從復制redis中主從節點復制數據有全…

OpenCL memory object 之 Global memory (1)

這篇日志是學習AMD OpenCL文檔時候的總結。 OpenCL用memory object在host和device之間傳輸數據&#xff0c;memory object由runtime&#xff08;運行庫&#xff0c;driver的一部分&#xff09;來管理。 OpenCL中的內存對象包括buffer以及image&#xff0c;buffer是一維數據元素…

Docker: dockerfile 使用介紹

Docker簡介 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Docker項目提供了構建在Linux內核功能之上&#xff0c;協同在一起的的高級工具。其目標是幫助開發和運維人員更容易地跨系統跨…

【Hello CSS】第六章-文檔流與排版

作者&#xff1a;陳大魚頭github&#xff1a; KRISACHAN正常流 什么是“正常流”&#xff1f; 其實就是我們日常所說的“文檔流”。 在W3C官方文檔里對應的是“normal flow”。 正常流的盒子屬于格式化上下文(FC)&#xff0c;在CSS2.2中可以是表格、塊或內聯。 在CSS3中引入了f…

創建型模式---工廠模式

工廠模式 在工廠設計模式中&#xff0c;客戶端可以請求一個對象&#xff0c;而無需要知道這個對象來自哪里&#xff0c;也就是使用哪個類來生成這個對象。工廠背后的思想是簡化對象的創建。與客戶端自己基于類實例化直接創建對象相比&#xff0c;基于一個中心化函數來實現&…

OpenCL memory object 之 Global memory (2)

當我們用clCreateBuffer, clCreateImage創建OpenCL memory object時候&#xff0c;我們需要輸入一個flag參數&#xff0c;這個參數決定memory object的位置。 cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errc…

數據結構進階篇-跳表

大家想必都知道&#xff0c;數組和鏈表的搜索操作的時間復雜度都是O(N)的&#xff0c;在數據量大的時候是非常耗時的。對于數組來說&#xff0c;我們可以先排序&#xff0c;然后使用二分搜索&#xff0c;就能夠將時間復雜度降低到O(logN)&#xff0c;但是有序數組的插入是一個O…

查看本機ssh公鑰,生成公鑰

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 查看ssh公鑰方法&#xff1a; 1.通過命令窗口&#xff1a;打開你的git bash 窗口&#xff0c;進入.ssh目錄&#xff1a;cd ~/.ssh&…

如何實現動態水球圖 --》 echars結合echarts-liquidfill實現

1&#xff09;項目中作為項目依賴&#xff0c;安裝到項目當中(注意必須要結合echars) npm install echarts vue-echarts --save npm install echarts-liquidfill --save 2&#xff09;在需要使用水晶球的組件里引入liquidFill.js import echarts-liquidfill/src/liquidFill.js;…

OpenCL memory object 之選擇傳輸path

對應用程序來說&#xff0c;選擇合適的memory object傳輸path可以有效提高程序性能。 下面先看一寫buffer bandwidth的例子&#xff1a; 1. clEnqueueWriteBuffer()以及clEnqueueReadBuffer() 如果應用程序已經通過malloc 或者mmap分配內存&#xff0c;CL_MEM_USE_HOST_PTR是個…

struts入門超詳細

https://blog.csdn.net/yerenyuan_pku/article/details/52652262轉載于:https://www.cnblogs.com/liuna369-4369/p/10870873.html

RabbitMQ 從入門到精通 (一)

目錄 1. 初識RabbitMQ2. AMQP3.RabbitMQ的極速入門4. Exchange(交換機)詳解4.1 Direct Exchange4.2 Topic Exchange4.3 Fanout Exchange5. Message 消息1. 初識RabbitMQ RabbitMQ 是一個開源的消息代理和隊列服務器&#xff0c;用來通過普通協議在完全不同的應用之間共享數據&a…

接收并解析消息體傳參、解析 json 參數

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.場景&#xff1a;postman 發送了一個 post 請求&#xff0c;如下&#xff1a; 2. 解析方式為用一個 vo 對象來接收 json。把 json 中的…

OpenCL memory object 之 傳輸優化

首先我們了解一些優化時候的術語及其定義&#xff1a; 1、deferred allocation&#xff08;延遲分配&#xff09;&#xff0c; 在第一次使用memory object傳輸數據時&#xff0c;runtime才對memory object真正分配空間。 這樣減少了資源浪費&#xff0c;但第一次使用時要慢一些…

VBS使文本框的光標位于所有字符后

有時候在文本框里會顯示一部分提示信息&#xff0c;用戶在這些提示信息后面輸入文本&#xff0c;但是將焦點設置于文本框后&#xff0c;光標總是在文本框的最前面&#xff0c; 用戶輸入的時候需要按"-->"鍵將光標移到最后才能輸入&#xff0c;這樣的操作很不爽。我…