漲薪技術|使用Dockerfile創建鏡像

上次的推文內容中介紹了如何使用docker commit的方法來構建鏡像,相反推薦使用被稱為Dockerfile的定義文件和docker build命令來構建鏡像。Dockerfile使用基本的基于DSL語法的指令來構建一個Docker鏡像,之后使用docker build命令基于該Dockerfile中的指令構建一個新的鏡像。

一、第一個Dockerfile

現在來創建一個最簡單的Dockerfile文件樣例,先創建一個空的Dockerfile文件,在任意目錄下都行,在Dockerfile文件中填入以下內容:

FROM alpine:3.14//設置容器內的數據卷VOLUME ["/var/html"]EXPOSE 80

該Dockerfile由一系列指令和參數組成,每條指令,如FROM,都必須為大寫字母且后面跟隨一個參數:FROM alpine:3.14,Dockerfile中的指令會按順序從上到下執行,所以應該根據需要合理安排指令的順序。

使用build命令構建鏡像的步驟如下 :???????

root@ubuntu:/home/test# docker build -t nginx:v1.0 .Sending build context to Docker daemon 8.65MBStep 1/3 : FROM alpine:3.143.14: Pulling from library/alpinea0d0a0d46f8b: Pull completeDigest: sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6aStatus: Downloaded newer image for alpine:3.14---> 14119a10abf4Step 2/3 : VOLUME ["/var/html"]---> Running in baa52a8c37bdRemoving intermediate container baa52a8c37bd---> 83ba81539ce7Step 3/3 : EXPOSE 80---> Running in b0b0efd15aa3Removing intermediate container b0b0efd15aa3---> d10277ba6308Successfully built d10277ba6308Successfully tagged nginx:v1.0

第一步:Docker從基礎鏡像運行一個容器。

第二步:執行數據卷指令來創建一個數據卷。

第三步:設置訪問端口

最后所有指令執行完畢。

每個Dockerfile的第一條指令都應該是FROM,FROM指令指定一個已經存在的鏡像后續指令都將基于該鏡像進行,這個鏡像被稱為基礎鏡像(base iamge)。在上面的Dockerfile示例中,我們指定了alpine:3.14作為鏡像的基礎鏡像,基于這個Dockerfile構建的新鏡像將以alpine:3.14操作系統為基礎,在運行一個容器時,必須要指明是基于哪個基礎鏡像在進行構建。

接著是VOLUME指令,用于指定數據卷的設置。

最后設置EXPOSE指令,這條指令告訴Docker該容器內的應用程序將會使用容器的指定端口,這并不意味著可以自動訪問任意容器運行中服務的端口,這里指定的是80端口。

二、Dockerfile指令

這里主要針對Dockerfile文件中使用到的指令進行介紹,介紹Dockerfiler文件中常用的指令,在Dockerfile文件中所有的指令都必須使用大寫。

1)FROM

FROM指令的格式如下:???????

FROM [--platform=<platform>] <image> [AS <name>]ORFROM [--platform=<platform>] <image>[:<tag>] [AS <name>]ORFROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

FROM指令表示初始化一個新構建并作為后續指令的基本映像,所以一個有效的Dockerfile文件必須以FROM指令開始,為個鏡像也必須是一個有效鏡像,可以從一些公用庫中來獲取相應的鏡像。

但ARG可以放在FROM指令前面,關于ARG和FROM如何交互將會在后面介紹。

FROM可以在單個Dockerfile中多出現,這樣可以創建多個映像,或將一個構建階段用作另一個構建階段的依賴庫。

FROM指令可以支持由其上一個指令ARG指令聲明的變量,并傳遞給FROM指令使用。???????

ARG CODE_VERSION=latestFROM base:${CODE_VERSION}CMD /code/run-appFROM extras:${CODE_VERSION}CMD /code/run-extras

2.RUN

RUN指令有兩種運行方式:???????

#shell格式:RUN <command>#exec格式:RUN ["executable", "param1", "param2"]# 例如:# RUN ["./test.php", "dev", "offline"] 等價于 RUN ./test.php dev offline

注意:Dockerfile的指令每執行一次都會在docker上新建一層,所以過多無意義的層,會造成鏡像膨脹過大。???????

FROM centosRUN yum install wgetRUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"RUN tar -xvf redis.tar.gz以上執行會創建 3 層鏡像。可簡化為以下格式:FROM centosRUN yum install wget \&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \&& tar -xvf redis.tar.gz

如上,以 && 符號連接命令,這樣執行后,只會創建 1 層鏡像。

3.CMD

CMD指令用于指定一個容器啟動時所運行的命令,這有點類似于RUN指令,但RUN指令是指定鏡像被構建時要運行的命令,而CMD是指容器啟動時所要運行的命令,CMD指令有三種形式。???????

#exec格式CMD ["executable","param1","param2"]# 該寫法是為 ENTRYPOINT 指令指定的程序提供默認參數CMD ["param1","param2"]#shell格式CMD command param1 param2

一般推薦使用第一種格式,執行過程清晰明確。第三種格式其實在運行過程中也會轉換成第一種格式運行,并且默認可執行文件是sh。

CMD和使用docker run命令啟動容器時指定運行命令幾乎一致。???????

#如在Dockerfile文件中寫以下指令CMD ["/bin/true"]#上面這個CMD等同以下面的run指令root@ubunhomhome/test# docker run -it nginx /bin/true

在Dockerfile中只能有一個CMD指令,即使如果有多個CMD指令,也只有最后一個CMD才會生效。

CMD指令主要是為執行中的容器提供默認值,這些默認值可以包含可執行文件,也可以省略可執行文件,在這種情況下,就必須指定一條ENTRYPOINT指令。

如果用戶在使用docker run指定參數時,則它們將會覆蓋Dockerfile文件中的CMD參數默認值。

4.LABEL

LABEL指令用來給鏡像添加一些元數據(metadata),以鍵值對的形式,語法格式如下:

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

如果LABEL值中需要跨多行,則需要加入反斜杠和引號。???????

LABEL "com.example.vendor"="chuanshi"LABEL com.example.label-with-value="test"LABEL version="3.0"LABEL description="This text illustrates \that label-values can span multiple lines."

一個鏡像可以有多個標簽,可以在一行上指定多個標簽,有以下兩種方式可以實現。???????

LABELLearn more about the "LABEL" Dockerfile command.multi.label1="value1" multi.label2="value2" other="value3"LABEL multi.label1="value1" \multi.label2="value2" \other="value3"

5.EXPOSE

該指令用于聲明監聽的端口號,在監聽是可以指定是TCP還是UDP協議,默認值為TCP,其主要有以下作用:

  • 幫助鏡像使用理解這個鏡像服務的守護端口,以方便配置映射。

  • 在運行時使用隨時端口映射,也就是docker run -P時,會自動隨機映射EXPOSE的端口。

EXPOSE指令實際上并未發布指定端口,它是將我們訪問時輸入的端口和運行容器之間做一種關聯或通信,具體發布哪些端口,要在運行容器時發布實際端口,可以使用docker run中-p或-P來設置映射的端口號。

默認情況下一般如果我們未指定協議的話,那么都是使用TCP協議,當然也可以指定具體的協議,也可以同時指定TCP和UDP協議。???????

EXPOSE 80/tcpEXPOSE 80/udp

6.ENV

設置環境變量,定義了環境變量,這樣在后續的指令中,就可以使用這個環境變量。如果在環境變量引用過程中包含空格,那么需要使用到反斜杠。

其語法格式如下:???????

ENV <key> <value>ENV <key1>=<value1> <key2>=<value2>...ENV MY_NAME="John Doe"ENV MY_DOG=Rex\ The\ DogENV MY_CAT=fluffy

使用ENV設置的環境變量會保留下來,當容器運行時可以使用docker inspect查看值,并且可以使用docker run --env = 更改環境變量的值。

如果僅僅是在構建過程中需要環境變量,而在最終映像中不需要,可以考慮為單個命令設置一個值或使用ARG,ARG指令不會人保留在最終鏡像中。???????

ARG DEBIAN_FRONTEND=noninteractiveRUN apt-get update && apt-get install -y ...

7.ARG

ARG構建參數與ENV作用一致,不過作用域不一樣,ARG設置的環境變量僅對Dockerfile內有效,也就是說只有docker build的過程中有效,構建好的鏡像內不存在此環境變量。

構建命令docker build中可以用--build-arg <參數名>=<值>來覆蓋,ARG指令格式如下:

ARG <參數名>[=默認值]

如果ARG指令具有默認值,并且在構建時未傳遞任何值,則構建時會使用默認值,相反如果未設置默認值,并且在構建中未傳遞任何值,那么構建時會輸出警告信息。

8.ADD

ADD指令是指將宿主機的文件或目錄復制到鏡像文件系統中指定的路徑,其語法格式有兩種:???????

ADD [--chown=<user>:<group>] <src>... <dest>ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

每個可以使用通配符,并且匹配將使用Go的filepath.Match規則進行,例如:要添加所有以“hom”開頭的文件:

ADD hom* /mydir/

“?”可以替換任意一個字符,例如:

ADD hom?.txt /mydir/

是指構建容器的路徑,可以是絕對路徑,也可以是相對路徑,但這個相對路徑是相對于WORKDIR的路徑。如以下示例是將“test.txt”文件添加到/relativeDir/。

ADD test.txt relativeDir/

下面的示例則是將“test.txt”添加到相對路徑/absoluteDie/中。

ADD test.txt /absoluteDir/

如果路徑中包含一些特字符,那么需要按照Golang規則轉義那些路徑,以防止在解析過程中將它們視為匹配的模式,如要添加名為sarr[1].txt的文件。

ADD sarr[[]1].txt /mydir/

路徑必須是構建內容的一個內部路徑,不能添加類似于ADD ../path /path,因為docker build的第一步是將上下文目錄和子目錄發送到docker守護進程。

如果是URL,而不以斜杠結尾,則從URL下載文件并將其復制到。

如果是URL,而以斜杠結尾,則從URL推斷文件名,并將文件下載到/,例如ADD http://chuanshi.com/foobar /,將創建文件/foobar,該URL必須具有正確的路徑,以便在這種情況下可以找到適當的文件名。

如果是目錄,則復制目錄的整個內容,包括文件系統元數據。

如果是任何其他類型的文件,則會將其及其元數據一起單獨復制,在這種情況下,如果以斜杠結尾,則它將被視為目錄,并且的內容將被寫在/base()中。

如果直接或由于使用通配符而指定多個資源,則必須是目錄,并且必須以斜杠結尾。

如果不以斜杠結尾,則將其視為常規文件,并且的內容將被寫入。

如果不存在,則會與路徑中所有缺少的目錄一起創建它。

9.COPY

復制指令,從上下文目錄中復制文件或者目錄到容器里指定路徑,通常有以下兩種格式:???????

COPY [--chown=<user>:<group>] <src>... <dest>COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

COPY指令表示從復制新文件或目錄,并將它們添加到容器的文件系統中,路徑為。

可以指定多個資源,但是文件和目錄的路徑將被解釋為相對于構建上下文。

每個可能包含通配 符,并且匹配將合作Go人filepath.Match規則進行。

例如要添加所有"hom"開頭的文件:

COPY home* /mydir/

"?"表示可以匹配任意一個字符:

COPY hom?.txt /mydir/

是指構建容器的路徑,可以是絕對路徑,也可以是相對路徑,但這個相對路徑是相對于WORKDIR的路徑。如以下示例是將“test.txt”文件添加到/relativeDir/。

COPY test.txt relativeDir/

下面的示例則是將“test.txt”添加到相對路徑/absoluteDie/中

COPY test.txt /absoluteDir/

如果路徑中包含一些特字符,那么需要按照Golang規則轉義那些路徑,以防止在解析過程中將它們視為匹配的模式,如要添加名為sarr[1].txt的文件。

COPY sarr[[]1].txt /mydir/

路徑必須是構建內容的一個內部路徑,不能添加類似于COPY ../path /path,因為docker build的第一步是將上下文目錄和子目錄發送到docker守護進程。

如果是目錄,則復制目錄的整個內容,包括文件系統無數據,目錄本身不會被復制,只是其內容被復制。

如果是任何其他類型的文件,則會將其及其元數據一起單獨復制,在這種情況下,如果以斜杠結尾,則它將被視為目錄,并且的內容將被寫在/base()中。

如果直接或由于使用通配符而指定多個資源,則必須是目錄,并且必須以斜杠結尾。

如果不以斜杠結尾,則將其視為常規文件,并且的內容將被寫入。

如果不存在,則會與路徑中所有缺少的目錄一起創建它。

10.ENTRYPOINT

類似于CMD指令,但其不會被docker run指令運行參數所覆蓋,并且這些命令行參數會被當作參數送給ENTRYPOINT指令指定的程序。

但是如果運行docker run時使用了--entrypoint選項,將覆蓋CMD指令指定的程序。

其語法格式有以下兩種:???????

#exec格式ENTRYPOINT ["executable", "param1", "param2"]#shell格式ENTRYPOINT command param1 param2

ENTRYPOINT的優點在執行docker run的時候可以指定ENTRYPOINT運行所需要的參數。

但如果Dockerfile中如果存在多個ENTRYPOINT指令時,只有最后一個會生效。

可以將ENTRYPOINT與CMD命令搭配使用,一般是變參才會使用CMD,這里的CMD等于是在給ENTRYPOINT傳參。

例如,通過Dockerfile構建了一個nginx:V1.0的鏡像。???????

FROM nginxENTRYPOINT ["nginx", "-c"] # 定參CMD ["/etc/nginx/nginx.conf"] # 變參

如果在運行容器時,不傳參運行

root@ubunhomhome/test# docker run -it nginx:v1.0

容器內則會默認運行以下命令,啟動主進程

nginx -c /etc/nginx/nginx.conf

如果在運行容器時傳參運行

root@ubunhomhome/test# docker run -it nginx:v1.0 -c /etc/nginx/new_nginx.conf

容器內會默認運行以下命令,啟動主進程

nginx -c /etc/nginxnew_nginx.conf

11.VOLUME

VOLUME指令在16.7小節會進行詳細的介紹,在本小節中不做介紹;

12.USER

USER指令用于指定執行后續命令的用戶和用戶組,這邊只是切換后續指令執行的用戶(用戶和用戶組必須提前已經存在)。其語法格式如下:???????

USER <user>[:<group>]#orUSER <UID>[:<GID>]

13.WORKDIR

WORKDIR指令表示指定工作目錄,該指定的目錄必須提前創建好,docker build構建鏡像過程中的,每個RUN命令都是新建的一層,只有通過WORKDIR創建才會一直存在。其語法格式如下:

WORKDIR /path/to/workdir

WORKDIR指令可在Dockerfile中多次使用,如果提供了相對路徑,則它將相對于上一個WORKDIR指令的路徑來創建目錄,如:???????

WORKDIR /aWORKDIR bWORKDIR cRUN pwd

該Dockerfile中最后一個pwd命令的輸出為/a/b/c。

WORKDIR指令也可以解析ENV設置的環境變量,如:???????

ENV DIRPATH=/pathWORKDIR $DIRPATH/$DIRNAMERUN pwd

該Dockerfile中最后一個pwd命令的輸出為/path/$DIRNAME。

?

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

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

相關文章

rkipc的h265設置

資料的位置 源代碼在luckfox-pico/project/app/rkipc/rkipc/src/rv1106_ipc/video/video.c中&#xff0c;使用了rkmpi庫&#xff0c;參考資料為"doc/zh/media/Rockchip_Developer_Guide_MPI.pdf" 通道設置設置 H265的通道設置主要由rkipc_pipe_0_init完成&#xf…

成都國際數字影像產業園:打造數字影像產業新高地

成都國際數字影像產業園&#xff1a;打造數字影像產業新高地 成都國際數字影像產業園正致力于構筑數字影像產業的新高地&#xff0c;成為推動區域數字經濟發展的重要引擎。 核心定位與目標 該園區精準定位于數字影像文創產業&#xff0c;旨在打造集內容創作、技術研發、人才…

各類神經網絡學習:(三)RNN 循環神經網絡(中集),同步多對多結構的詳細解釋

上一篇下一篇RNN&#xff08;上集&#xff09;RNN&#xff08;下集&#xff09; 同步多對多結構 1&#xff09;結構詳解 ①圖解&#xff1a; ②參數含義&#xff1a; x t x_t xt? &#xff1a;表示每一個時刻的輸入&#xff1b; o t o_t ot? &#xff1a;表示每一個時刻的輸…

Perl 環境安裝指南

Perl 環境安裝指南 引言 Perl是一種廣泛使用的解釋型、動態編程語言,以其強大的文本處理能力和靈活性著稱。本文將為您詳細介紹Perl環境的安裝過程,包括系統要求、安裝步驟以及注意事項。 系統要求 在安裝Perl之前,請確保您的計算機滿足以下基本要求: 操作系統:Window…

【嵌入式學習2】C語言 - VScode環境搭建

目錄 ## 語言分類 ## c語言編譯器 ## VScode相關配置 ## 語言分類 編譯型語言&#xff1a;C&#xff0c;C解釋型語言&#xff1a;python&#xff0c;JS ## c語言編譯器 分類GCC 系列MinGWCygwinMSVC系列一套編程語言編譯器將GCC編譯器和GNU Binutils移植到Win32平臺下的產物…

qt+opengl 加載三維obj文件

1前面我們已經熟悉了opengl自定義頂點生成一個立方體&#xff0c;并且我們實現了立方體的旋轉&#xff0c;光照等功能。下面我們來用opengl來加載一個obj文件。準備我們首先準備一個簡單的obj文件&#xff08;head.obj&#xff09;。資源在本頁下載 2 在obj文件里面&#xff0c…

0326-Java 字符串方法

package com.qc.字符串;import java.util.Arrays;public class Test {public static void main(String[] args) { // String x"hello";//字符串 char[] // x x"demo";//字符串拼接 // xx2450; // xxtrue; // System.out.println(x);//hellodemo2450t…

<command-line>:0:1: error: macro names must be identifiers m

報錯&#xff1a;:0:1: error: macro names must be identifiers 排查類很久 原來是&#xff1a; add_compile_definitions(_GLIBCXX_USE_CXX11_ABI$ABI_VERSION)寫成了 add_compile_definitions(-D_GLIBCXX_USE_CXX11_ABI$ABI_VERSION)多了個 -D。

風光互補智慧路燈的燈桿設計有哪些要求?

嘿&#xff0c;朋友們&#xff01;叁仟風光互補智慧路燈的燈桿設計那可是超級重要的事兒&#xff0c;得全方位綜合考量各種因素&#xff0c;就是為了確保咱們的路燈能兼具超棒的功能性、絕對的安全性、無敵的美觀性以及超厲害的耐用性&#xff01;下面就來看看這些超贊的常見要…

06、RAG

LLM的知識僅限于它所接受到的訓練數據。如果我們希望讓它了解特定領域的專有知識&#xff0c;則可以使用下面的方式操作&#xff1a; 使用RAG使用專有數據對LLM進行微調RAG與數據微調方式結合使用 什么是RAG 簡單地說&#xff0c;RAG就是把數據發送給LLM之前從數據中查找相關…

自然語言處理:第一百零二章 如何去掉DeepSeek R1思考過程

本人項目地址大全&#xff1a;Victor94-king/NLP__ManVictor: CSDN of ManVictor 寫在前面: 筆者更新不易&#xff0c;希望走過路過點個關注和贊&#xff0c;筆芯!!! 寫在前面: 筆者更新不易&#xff0c;希望走過路過點個關注和贊&#xff0c;筆芯!!! 寫在前面: 筆者更新不易…

flink 安裝與訪問 ui

官方文檔&#xff1a;First steps | Apache Flink 版本&#xff1a;v2.0.0 下載Flink Flink運行在所有類UNIX環境中&#xff0c;即Linux&#xff0c;Mac OS X和Cygwin&#xff08;適用于Windows&#xff09;。您需要安裝Java 11。要檢查安裝的Java版本&#xff0c;請在終端中…

WPF TextBox實現鍵盤enter后實時讀取TextBox中的值

代碼 <TextBox Grid.Column"0" x:Name"textBox" Margin"10,5,0,5" TextWrapping"Wrap" Text"{Binding SendMessage,UpdateSourceTriggerPropertyChanged}" VerticalContentAlignment"Center" CaretBrush&qu…

PyTorch實現Transformer模型

首先&#xff0c;我得回顧一下Transformer的基本結構&#xff0c;確保自己沒有記錯。Transformer由編碼器和解碼器組成&#xff0c;每個編碼器層包含多頭自注意力機制和前饋網絡&#xff0c;解碼器層則還有編碼器-解碼器注意力。 接下來&#xff0c;用戶需要的是手把手的代碼解…

詳細介紹sentinel的使用,并列舉經常出的面試題以及答案

Sentinel 是一款由阿里巴巴開源的分布式系統的流量防衛系統&#xff0c;能夠實時響應并滿足高并發的流量控制需求。它提供了流量監控、流量控制、熔斷降級、系統保護等核心功能&#xff0c;可幫助開發人員實時發現系統的流量異常并快速做出相應的限流策略。 Sentinel 的使用步…

mysql-connector-java-5.1.37.jarJava連接器

mysql-connector-java-5.1.37.jar是MySQL官方提供的Java連接器&#xff0c;用于在Java應用程序中與MySQL數據庫進行通信。具體來說&#xff0c;這個JAR文件是MySQLJDBC驅動程序的一個版本&#xff0c;允許Java程序通過JDBC&#xff08;JavaDatabaseConnectivity&#xff09;接口…

Python基于Django的智能旅游推薦系統(附源碼,文檔說明)

博主介紹&#xff1a;?IT徐師兄、7年大廠程序員經歷。全網粉絲15W、csdn博客專家、掘金/華為云//InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精彩專欄推薦訂閱&#x1f447;&#x1f3…

【博客節選】再談Unity 的 root motion

節選自 【Unity實戰筆記】第二十三 root motion變更方向攻擊 &#xff08;OnStateMove rootmotion rigidbody 使用的一些問題&#xff09; 小伙伴們應該對root motion非常困惑&#xff0c;包括那個bake into pose。 當xz bake into pose后&#xff0c;角色攻擊動畫與父節點產…

網站服務器常見的CC攻擊防御秘籍!

CC攻擊對網站的運營是非常不利的&#xff0c;因此我們必須積極防范這種攻擊&#xff0c;但有些站長在防范這種攻擊時可能會陷入誤區。讓我們先了解下CC攻擊&#xff01; CC攻擊是什么 CC是DDoS攻擊的一種&#xff0c;CC攻擊是借助代理服務器生成指向受害主機的合法請求&#x…

JAVA:Spring Boot @Conditional 注解詳解及實踐

1、簡述 在 Spring Boot 中&#xff0c;Conditional 注解用于實現 條件化 Bean 裝配&#xff0c;即根據特定的條件來決定是否加載某個 Bean。它是 Spring 框架中的一個擴展機制&#xff0c;常用于實現模塊化、可配置的組件加載。 本文將詳細介紹 Conditional 相關的注解&…