<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          構(gòu)建鏡像的核心文件 Dockerfile

          共 14802字,需瀏覽 30分鐘

           ·

          2022-07-17 02:50

          點擊關(guān)注公眾號,Java干貨及時送達(dá)


          Java術(shù) | 


          Dockerfile 是一個用來構(gòu)建鏡像的文本文件,文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說明。

          通過Dockerfile我們能夠?qū)㈨椖繕?gòu)建成一個鏡像,這樣的好處是可以將一個復(fù)雜的項目直接打包成一個鏡像存儲和運行。

          Dockerfile提供了非常多的指令供我們操作,下面例舉一些常用的命令:

          指令作用
          FROM指定當(dāng)前鏡像是基于哪個鏡像的
          RUN構(gòu)建鏡像時需要運行的指令
          EXPOSE當(dāng)前容器對外暴露的端口號
          WORKDIR指定在創(chuàng)建容器后終端默認(rèn)登錄進(jìn)來的工作目錄
          ENV用于在構(gòu)建鏡像過程中設(shè)置環(huán)境變量
          ADD將宿主機(jī)目錄下的文件拷貝到鏡像
          COPY拷貝文件和目錄到鏡像
          VOLUME容器數(shù)據(jù)卷,用于數(shù)據(jù)持久化
          CMD指定一個容器啟動時要運行的命令
          ENTRYPOINT指定一個容器啟動時要運行的命令

          FROM

          該指令用于指定當(dāng)前鏡像是基于哪個鏡像進(jìn)行構(gòu)建的,因為鏡像的構(gòu)建是一層一層進(jìn)行的,Docker Server會先基于某個基礎(chǔ)鏡像將項目打包成一個新鏡像,再基于這個新鏡像繼續(xù)打包,以此類推,不斷打包構(gòu)建,最終生成一個處理完成的鏡像。

          下面就來簡單地使用一下FROM指令,在/opt目錄下新建一個test目錄,并創(chuàng)建Dockerfile文件,編寫如下內(nèi)容:

          FROM centos

          文件內(nèi)容非常簡單,此時我們就可以根據(jù)Dockerfile進(jìn)行鏡像構(gòu)建了,執(zhí)行指令:

          docker build -t mycentos_test01 .

          這里我們指定FROM為centos,Docker Server將基于centos鏡像進(jìn)行構(gòu)建,當(dāng)Docker中沒有該鏡像時,還會先將centos鏡像拉取下來再進(jìn)行構(gòu)建, . 表示Dockerfile文件所在的位置為當(dāng)前目錄:

          [root@localhost test]# docker build -t mycentos_test01 .
          Sending build context to Docker daemon  2.048kB
          Step 1/1 : FROM centos
          latest: Pulling from library/centos
          7a0437f04f83: Pull complete
          Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
          Status: Downloaded newer image for centos:latest
           ---> 300e315adb2f
          Successfully built 300e315adb2f
          Successfully tagged mycentos_test01:latest

          當(dāng)指令執(zhí)行成功后,就會生成一個新的鏡像,可以使用 docker images 指令進(jìn)行查看:

          [root@localhost test]# docker images
          REPOSITORY        TAG            IMAGE ID       CREATED        SIZE
          centos            latest         300e315adb2f   7 months ago   209MB
          mycentos_test01   latest         300e315adb2f   7 months ago   209MB

          此時我們就可以啟動這個鏡像,同時進(jìn)入交互終端:

          docker run -it mycentos_test01
          [root@31c51ab4d120 /]# ls
          bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

          可以看到這就是一個新的centos,這是因為我們只使用了FROM指令基于centos鏡像構(gòu)建,所以得到的鏡像仍然還是一個基礎(chǔ)的centos鏡像。

          需要注意的是Dockerfile文件中的第一條指令必須是 FROM 。

          RUN

          該指令會將在當(dāng)前鏡像之上的新層中執(zhí)行任何命令并提交結(jié)果,生成的鏡像將用于下一步。

          修改Dockerfile文件,內(nèi)容如下:

          FROM centos
          RUN yum install -y vim

          我們知道在沒加RUN命令之前構(gòu)建出來的鏡像就是一個centos,但現(xiàn)在,構(gòu)建出來的鏡像就是一個包含vim編輯器的centos系統(tǒng),馬上來構(gòu)建它:

          docker build -t mycentos_test02 .

          構(gòu)建成功后就可以進(jìn)行啟動:

          docker run -it mycentos_test02

          可以檢查一下鏡像中是否真的已經(jīng)包含了vim編輯器:

          [root@46992a057ea4 /]# rpm -qa|grep vim
          vim-minimal-8.0.1763-15.el8.x86_64
          vim-common-8.0.1763-15.el8.x86_64
          vim-enhanced-8.0.1763-15.el8.x86_64
          vim-filesystem-8.0.1763-15.el8.noarch

          RUN指令還支持以數(shù)組的方式傳遞需要執(zhí)行的命令,比如:

          RUN ["yum","install","-y","vim"]

          EXPOSE

          該指令用于指定構(gòu)建的鏡像在運行時為對外暴露的端口,只有向外暴露了端口,外部才能夠訪問到這個進(jìn)鏡像提供的服務(wù)。

          修改Dockerfile文件:

          FROM centos
          RUN ["yum","install","-y","vim"]
          EXPOSE 80

          但事實上centos鏡像添加端口并沒有作用,因為它不像tomcat、mysql、redis那樣會向外部主機(jī)提供某項服務(wù),所以可以將基礎(chǔ)鏡像指定為tomcat:

          FROM tomcat:8.0

          此時構(gòu)建鏡像然后啟動:

          docker run -p 80:80 mytomcat_test01

          CMD

          該指令用于為啟動的容器指定需要執(zhí)行的命令,修改Dockerfile:

          FROM centos
          RUN ["yum","install","-y","vim"]
          EXPOSE 80
          CMD ["echo","hello"]

          構(gòu)建鏡像:

          docker build -t mycentos_test03

          此時啟動鏡像:

          docker run -it mycentos_test03

          因為CMD指令的作用,所以在啟動這個鏡像的時候就會立馬執(zhí)行CMD中的命令,從而輸出 hello 字符串:

          [root@localhost test]# docker run -it mycentos_test03
          hello

          需要注意的是Dockerfile中只能有一條CMD命令,如果寫出了多條CMD,則以最后一條的內(nèi)容為準(zhǔn)。

          ENTRYPOINT

          該指令與CMD類似,也是用于指定容器啟動時需要執(zhí)行的命令,修改Dockerfile文件:

          FROM centos
          RUN ["yum","install","-y","vim"]
          EXPOSE 80
          ENTRYPOINT ["echo","hello"]

          構(gòu)建鏡像:

          docker build -t mycentos_test04 .

          啟動鏡像:

          [root@localhost test]# docker run -it mycentos_test04
          hello

          可以看到ENTRYPOINT和CMD兩個指令的效果是一樣的,那么它倆有什么區(qū)別呢?其區(qū)別在于命令的覆蓋方式,對于CMD指令,我們可以在啟動鏡像的時候直接拼寫命令來覆蓋它,比如:

          [root@localhost test]# docker run -it mycentos_test03 echo hello centos
          hello centos

          此時在Dockerfile中配置的CMD命令將會被這里的 echo hello centos 覆蓋掉,最終輸出 hello cnetos 。

          然而對于ENTRYPOINT,它是無法通過直接追加命令來覆蓋的,而是需要用到一個參數(shù):

          [root@localhost test]# docker run --entrypoint="echo hello centos" mycentos_test04
          hello centos

          由此可見,ENTRYPOINT指令對于命令的覆蓋是比CMD指令更加復(fù)雜的,為此,可以將那些基本固定不變的命令配置到ENTRYPOINT中,而將需要修改的命令配置到CMD中,比如:

          FROM centos
          RUN ["yum","install","-y","vim"]
          EXPOSE 80
          ENTRYPOINT ["echo"]
          CMD ["hello centos"]

          WORKDIR

          該指令用于指定鏡像的落腳點,即:啟動鏡像后初始進(jìn)入的目錄,若是沒有配置,則默認(rèn)是 / ,比如:

          [root@localhost test]# docker run -it mycentos_test02
          [root@9c958bd3830f /]#

          啟動鏡像后首先進(jìn)入的便是 / 目錄,但如果配置了WORKDIR:

          FROM centos
          WORKDIR /opt/work

          構(gòu)建鏡像:

          docker build -t mycentos_test05 .

          啟動鏡像:

          [root@localhost test]# docker run -it mycentos_test05
          [root@37f177c1e546 work]# pwd
          /opt/work

          需要注意,只要配置了WORKDIR,無論你有沒有在后續(xù)的指令中使用到它,WORKDIR配置的目錄是一定會在鏡像中被創(chuàng)建的。

          ENV

          該指令用于為鏡像設(shè)置環(huán)境變量,比如:

          FROM centos
          ENV name centos
          WORKDIR /$name

          在這里配置了一個環(huán)境變量name,值為centos,并在WORKDIR指令中引用了該變量,所以通過該文件構(gòu)建出來的鏡像在啟動時就會直接進(jìn)入/centos目錄,驗證一下:

          [root@localhost test]# docker build -t mycentos_test06 .
          Sending build context to Docker daemon  2.048kB
          Step 1/3 : FROM centos
           ---> 300e315adb2f
          Step 2/3 : ENV name centos
           ---> Running in 4c272c71fc62
          Removing intermediate container 4c272c71fc62
           ---> 0c00112be488
          Step 3/3 : WORKDIR /$name
           ---> Running in 19bb2ad9d3cb
          Removing intermediate container 19bb2ad9d3cb
           ---> d7405fa45cb0
          Successfully built d7405fa45cb0
          Successfully tagged mycentos_test06:latest
          [root@localhost test]# docker run -it mycentos_test06
          [root@0a505138f024 centos]# pwd
          /centos

          VOLUME

          該指令用于定義容器運行時可以掛載到宿主機(jī)的目錄,修改一下Dockerfile:

          FROM centos
          ENV name centos
          WORKDIR /$name
          VOLUME /$name

          此時配置了VOLUME,值為 /$name ,則容器中的/centos目錄就允許被外部掛載。

          構(gòu)建鏡像:

          docker build -t mycentos_test07 .

          然后在啟動鏡像的同時掛載一下數(shù)據(jù)卷:

          docker run -it -v /opt/centos:/centos mycentos_test07

          這樣兩個目錄就實現(xiàn)了共享,此時在/opt/centos目錄下的操作都會被同步到容器中的/centos目錄:

          [root@localhost test]# cd /opt/centos/
          [root@localhost centos]# touch test
          [root@localhost centos]# docker run -it -v /opt/centos:/centos mycentos_test07
          [root@37450c713b08 centos]# ls
          test

          ADD

          該指令用于將context目錄中指定的文件復(fù)制到鏡像的指令目錄中去,那么首先我們就要知道何為context目錄。

          context目錄意為上下文目錄,指的是Dockerfile文件所在的目錄,比如:

          [root@localhost opt]# ll
          total 262144
          drwx--x--x. 4 root  root         28 Jun 18 11:27 containerd
          -rw-r--r--. 1 root  root  268435456 Jun 23 15:46 disk.bin
          -rw-r--r--. 1 root  root          0 Jul 23 07:08 Dockerfile
          drwxr-xr-x. 3 root  root         25 Jul 22 12:45 javaproject
          drwxr-xr-x. 8 10143 10143       273 Apr  7 19:26 jdk1.8.0_291
          drwxr-xr-x. 2 root  root         24 Jul 23 07:04 test
          drwxr-xr-x. 8 root  root        160 Jul  5 12:52 zookeeper-3.5.7

          若是此時Dockerfile文件處在/opt目錄下,則context目錄則為/opt目錄,因為DockerServer會將context目錄中的所有文件,包括子目錄及其子文件進(jìn)行打包構(gòu)建,所以這也是為什么我們一開始創(chuàng)建一個空的文件夾,并將Dockerfile放在其中,因為文件過多會導(dǎo)致構(gòu)建速度變慢。

          修改Dockerfile:

          FROM centos
          ENV name centos
          WORKDIR /$name
          VOLUME /$name
          ADD test.txt /

          在Dockerfile所在目錄下有一個test.txt,現(xiàn)在要將其復(fù)制到容器中的 / 目錄下,構(gòu)建鏡像:

          docker build -t mycentos_test08 .

          啟動鏡像:

          [root@localhost test]# docker run -it mycentos_test08
          [root@184a8824b583 centos]# cd /
          [root@184a8824b583 /]# ls -l | grep test
          -rw-r--r--.  1 root root   0 Jul 23 07:25 test.txt

          若是想修改添加到容器后的文件名,則直接指定名字即可:

          ADD test.txt /ntest.txt

          ADD不僅能夠添加文件、目錄,還能夠添加一個url,比如:

          ADD http://www.baidu.com /test.html

          則啟動構(gòu)建后的鏡像時,便會在 / 目錄下創(chuàng)建test.html文件,并將訪問http://www.baidu.com所得到的響應(yīng)結(jié)果寫入該文件。

          構(gòu)建一個SpringBoot應(yīng)用的鏡像

          大概了解Dockerfile中的一些指令之后,我們就可以通過它來構(gòu)建一個SpringBoot應(yīng)用的鏡像了,所以首先來編寫一個非常簡單的SpringBoot應(yīng)用:

          @RestController
          public class TestController {
              
              @GetMapping("/testMethod")
              public String testMethod(){
                  return "success";
              }
          }

          創(chuàng)建一個控制器用于測試即可,然后將應(yīng)用打成一個jar包,使用maven插件即可進(jìn)行打包,指令如下:

          mvn clean package

          將得到的jar包上傳至服務(wù)器:

          [root@localhost ~]# cd /opt/test/
          [root@localhost test]# ls -l | grep .jar
          -rw-r--r--. 1 root root 16568766 Jul 23 07:56 SpringBootDemo-0.0.1-SNAPSHOT.jar

          編寫Dockerfile:

          FROM openjdk:8 # 指定基礎(chǔ)鏡像
          WORKDIR /test # 指定工作目錄
          ADD SpringBootDemo-0.0.1-SNAPSHOT.jar /test # 將jar包復(fù)制到容器中
          EXPOSE 8080 # 向外暴露8080端口
          ENTRYPOINT ["java","-jar"]
          CMD ["SpringBootDemo-0.0.1-SNAPSHOT.jar"]

          因為運行jar包需要JDK環(huán)境,所以直接使用openjdk8作為基礎(chǔ)鏡像即可,然后指定工作目錄,接著將jar包復(fù)制到容器里的工作目錄中,并向外暴露8080端口,最后使用ENTRYPOINT和CMD指令聯(lián)合組成jar包的運行命令。

          這樣就可以構(gòu)建鏡像了:

          docker build -t springbootdemo .

          運行鏡像:

          docker run -p 8080:8080 springbootdemo

          鏡像啟動后會自動運行jar包,此時外部主機(jī)就可以訪問到pringBoot應(yīng)用了:

          img

          上傳鏡像到服務(wù)器

          這里以阿里云為例,我們將剛才構(gòu)建的鏡像上傳至阿里云的鏡像服務(wù)器中,首先登錄阿里云,搜索 容器鏡像服務(wù) 并開通:

          img

          開通后進(jìn)入管理控制臺,點擊左側(cè)的命名空間,創(chuàng)建一個命名空間:

          img

          然后點擊左側(cè)的鏡像倉庫,創(chuàng)建一個鏡像倉庫:

          img

          選擇剛剛創(chuàng)建的命名空間,并填寫倉庫名稱:

          img

          點擊下一步后選擇本地倉庫:

          img

          點擊創(chuàng)建鏡像倉庫,完成后可以看到阿里云提供的操作指南,我們照著操作指南進(jìn)行操作即可。

          首先登錄到阿里云:

          docker login --username=取個名字好困難a registry.cn-hangzhou.aliyuncs.com

          然后會要求輸入密碼,密碼在開通容器鏡像服務(wù)的時候就會讓你設(shè)置,如果沒有設(shè)置密碼,也可以在頁面右側(cè)的新手引導(dǎo)中點擊訪問憑證進(jìn)行設(shè)置:

          img

          然后為鏡像設(shè)置tag:

          docker tag 8d4d7be1d926 registry.cn-hangzhou.aliyuncs.com/test_respository/springbootdemo:1.0.0

          這里有兩處地方需要設(shè)置(ImageId和版本號):

          docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/test_respository/springbootdemo:[鏡像版本號]

          其中ImageId為鏡像的id,通過 docker images 即可查詢到,鏡像版本號可以隨意填寫。

          最后將鏡像推送到服務(wù)器上:

          docker push registry.cn-hangzhou.aliyuncs.com/test_respository/springbootdemo:1.0.0

          此時點擊鏡像版本查看一下鏡像是否成功上傳了:

          img

          接下來測試一下拉取功能,首先刪除掉之前構(gòu)建的鏡像:

          docker rmi springbootdemo

          執(zhí)行指令進(jìn)行拉取:

          docker push registry.cn-hangzhou.aliyuncs.com/test_respository/springbootdemo:1.0.0
          [root@localhost ~]# docker images
          REPOSITORY                                                          TAG            IMAGE ID       CREATED             SIZE
          registry.cn-hangzhou.aliyuncs.com/test_respository/springbootdemo   1.0.0          8d4d7be1d926   41 minutes ago      531MB
          openjdk                                                             8              f67a59e543c1   19 hours ago        514MB
          centos                                                              latest         300e315adb2f   7 months ago        209MB
          mycentos_test01                                                     latest         300e315adb2f   7 months ago        209MB
          tomcat                                                              8.0            ef6a7c98d192   2 years ago         356MB

          拉取下來的鏡像就可以啟動了,只不過鏡像的名字變得比較長了:

          docker run -p 8080:8080 registry.cn-hangzhou.aliyuncs.com/test_respository/springbootdemo:1.0.0

          本文作者:汪偉俊 為Java技術(shù)迷專欄作者 投稿,未經(jīng)允許請勿轉(zhuǎn)載!

              

          1、拖動文件就能觸發(fā)7-Zip安全漏洞,波及所有版本

          2、進(jìn)程切換的本質(zhì)是什么?

          3、一次 SQL 查詢優(yōu)化原理分析:900W+ 數(shù)據(jù),從 17s 到 300ms

          4、Redis數(shù)據(jù)結(jié)構(gòu)為什么既省內(nèi)存又高效?

          5、IntelliJ IDEA快捷鍵大全 + 動圖演示

          6、全球第三瀏覽器,封殺中國用戶這種操作!(文末送書)

          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕第一 | 亚洲色大成网站www | 在线国内自拍 | 五月天堂影院 | 99热这里没有精品 |