5. Docker 生成鏡像
有時候從Docker鏡像倉庫中下載的鏡像不能滿足要求,我們可以基於一個基礎鏡像構建一個自己的鏡像
構建兩種方式:
-
更新鏡像:使用 docker commit 命令
-
構建鏡像:使用 docker build 命令,需要創建Dockerfile文件
5.1. 更新鏡像
先使用基礎鏡像創建一個容器,然後對容器內容進行更改,然後使用 docker commit 命令提交爲一個新的鏡像(以tomcat爲例)。
1.根據基礎鏡像,創建容器
docker run --name mytomcat -p 80:8080 -d tomcat
2.修改容器內容
docker exec -it mytomcat /bin/bash
cd webapps/ROOT
rm -f index.jsp
echo hello world > index.html
exit
3.提交爲新鏡像
docker commit -m="描述消息" -a="作者" 容器ID或容器名 鏡像名:TAG
# 例:
# docker commit -m="修改了首頁" -a="User01" mytomcat user01/tomcat:v1.0
4.使用新鏡像運行容器
docker run --name tom -p 8080:8080 -d user01/tomcat:v1.0
5.2. Dockerfile構建鏡像
5.2.1. 什麼是DockerFile
Dockerfile is nothing but the source code for building Docker images
-
Docker can build images automatically by reading the instructions from a Dockerfile
-
A Dockerfile is a text document that contains all the commands a user could call on the command lineto assemble an image
-
Using docker build users can create an automated build that executes several command-line instructionsin succession
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BmzTJkCy-1575377064050)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image005.jpg)]
5.2.2. Dockerfile格式
- Format:
- #Comment
- INSTRUCTION arguments
- The instruction is not case-sensitive
- However,convention is for them to be UPPERCASE to distinguish them from arguments more easily
- Docker runs instructions in a Dockerfile in order
- The first instruction must be ‘FROM’ in order to specify the Base Image from which you are building
5.2.3. 使用Dockerfile構建鏡像實例
一、準備
1.把你的springboot項目打包成可執行jar包
2.把jar包上傳到Linux服務器
二、構建
1.在jar包路徑下創建Dockerfile文件 vi Dockerfile
# 指定基礎鏡像,本地沒有會從dockerHub pull下來
FROM java:8
#作者
MAINTAINER user01
#把可執行jar包複製到基礎鏡像的根目錄下
ADD luban.jar /luban.jar
# 鏡像要暴露的端口,如要使用端口,在執行docker run命令時使用-p生效
EXPOSE 80
# 在鏡像運行爲容器後執行的命令
ENTRYPOINT ["java","-jar","/luban.jar"]
2.使用 docker build 命令構建鏡像,基本語法
docker build -t user01/mypro:v1 .
# -f指定Dockerfile文件的路徑
# -t指定鏡像名字和TAG
# .指當前目錄,這裏實際上需要一個上下文路徑
三、運行
運行自己的SpringBoot鏡像
docker run --name pro -p 80:80 -d 鏡像名:TAG
5.2.4. Dockerfile常用命令
5.2.4.1. FROM
FROM指令是最重要的一個並且必須爲Dockerfile文件開篇的第一個非註釋行,用於爲鏡像文件構建過程指定基礎鏡像,後續的指令運行於此基礎鏡像提供的運行環境。
這個基礎鏡像可以是任何可用鏡像,默認情況下docker build會從本地倉庫找指定的鏡像文件,如果不存在就會從Docker Hub上拉取
語法:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
5.2.4.2. MAINTAINER(depreacted)
Dockerfile的製作者提供的本人詳細信息
Dockerfile不限制MAINTAINER出現的位置,但是推薦放到FROM指令之後
語法:
MAINTAINER <name>
name可以是任何文本信息,一般用作者名稱或者郵箱
5.2.4.3. LABEL
給鏡像指定各種元數據
語法:
LABEL <key>=<value> <key>=<value> <key>=<value>..
一個Dockerfile可以寫多個LABEL,但是不推薦這麼做,Dockerfile每一條指令都會生成一層鏡像,如果LABEL太長可以使用\符號換行。構建的鏡像會繼承基礎鏡像的LABEL,並且會去掉重複的,但如果值不同,則後面的值會覆蓋前面的值。
5.2.4.4. COPY
用於從宿主機複製文件到創建的新鏡像文件
語法:
COPY <src>...<dest>
COPY ["<src>",..."<dest>"]
# <src>:要複製的源文件或者目錄,可以使用通配符
# <dest>:目標路徑,即正在創建的image的文件系統路徑;建議<dest>使用絕對路徑,否則COPY指令則以WORKDIR爲
其起始路徑
注意:如果你的路徑中有空白字符,通常會使用第二種格式
規則:
-
必須是build上下文中的路徑,不能是其父目錄中的文件
-
如果 是目錄,則其內部文件或子目錄會被遞歸複製,但 目錄自身不會被複制
-
如果指定了多個 ,或在 中使用了通配符,則 必須是一個目錄,則必須以/符號結尾
-
如果 不存在,將會被自動創建,包括其父目錄路徑
5.2.4.5. ADD
基本用法和COPY指令一樣,ADD支持使用TAR文件和URL路徑
語法:
ADD <src>...<dest>
ADD ["<src>",..."<dest>"]
規則:
-
和COPY規則相同
-
如果 爲URL並且 沒有以/結尾,則 指定的文件將被下載到
-
如果 是一個本地系統上壓縮格式的tar文件,它會展開成一個目錄;但是通過URL獲取的tar文件不會自動展開
-
如果 有多個,直接或間接使用了通配符指定多個資源,則 必須是目錄並且以/結尾
5.2.4.6. WORKDIR
用於爲Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定設定工作目錄,只會影響當前WORKDIR
之後的指令。
語法:
WORKDIR <dirpath>
在Dockerfile文件中,WORKDIR可以出現多次,路徑可以是相對路徑,但是它是相對於前一個WORKDIR指令指定的路徑另外,WORKDIR可以是ENV指定定義的變量
5.2.4.7. VOLUME
用來創建掛載點,可以掛載宿主機上的卷或者其他容器上的卷
語法:
VOLUME <mountpoint>
VOLUME ["<mountpoint>"]
不能指定宿主機當中的目錄,宿主機掛載的目錄是自動生成的
5.2.4.8. EXPOSE
用於給容器打開指定要監聽的端口以實現和外部通信
語法:
EXPOSE <port>[/<protocol>] [<port>[/<protocol>]...]
用於指定傳輸層協議,可以是TCP或者UDP,默認是TCP協議
EXPOSE可以一次性指定多個端口,例如: EXPOSE 80/tcp 80/udp
5.2.4.9. ENV
用來給鏡像定義所需要的環境變量,並且可以被Dockerfile文件中位於其後的其他指令(如ENV、ADD、COPY等)所調用,調用格式:{variable_name}
語法:
ENV <key> <value>
ENV <key>=<value>...
第一種格式中, 之後的所有內容都會被視爲 的組成部分,所以一次只能設置一個變量
第二種格式可以一次設置多個變量,如果 當中有空格可以使用\進行轉義或者對 加引號進行標識;
另外\也可以用來續行
5.2.4.10. ARG
用法同ENV
語法:
ARG <name>[=<default value>]
指定一個變量,可以在docker build創建鏡像的時候,使用 --build-arg = 來指定參數
5.2.4.11. RUN
用來指定docker build過程中運行指定的命令
語法:
RUN <command>
RUN ["<executable>","<param1>","<param2>"]
第一種格式裏面的參數一般是一個shell命令,以 /bin/sh -c 來運行它
第二種格式中的參數是一個JSON格式的數組,當中 是要運行的命令,後面是傳遞給命令的選項或者參數;但是這種格式不會用 /bin/sh -c 來發起,所以常見的shell操作像變量替換和通配符替換不會進行;如果你運行的命令依賴shell特性,可以替換成類型以下的格式
RUN ["/bin/bash","-c","",""]
5.2.4.12. CMD
容器啓動時運行的命令
語法:
CMD <command>
CMD ["<executable>","<param1>","<param2>"]
CMD ["<param1>","<param2>"]
前兩種語法和RUN相同
第三種語法用於爲ENTRYPOINT指令提供默認參數
RUN和CMD區別:
- RUN指令運行於鏡像文件構建過程中,CMD則運行於基於Dockerfile構建出的新鏡像文件啓動爲一個容器的時候
- CMD指令的主要目的在於給啓動的容器指定默認要運行的程序,且在運行結束後,容器也將終止;不過,CMD命令可以被docker run的命令行選項給覆蓋
- Dockerfile中可以存在多個CMD指令,但是隻有最後一個會生效
5.2.4.13. ENTRYPOINT
類似於CMD指令功能,用於給容器指定默認運行程序
語法:
ENTRYPOINT<command>
ENTRYPOINT["<executable>","<param1>","<param2>"]
和CMD不同的是ENTRYPOINT啓動的程序不會被docker run命令指定的參數所覆蓋,而且,這些命令行參數會被當做參數傳遞給ENTRYPOINT指定的程序(但是,docker run命令的–entrypoint參數可以覆蓋ENTRYPOINT)
docker run命令傳入的參數會覆蓋CMD指令的內容並且附加到ENTRYPOINT命令最後作爲其參數使用.同樣,Dockerfile中可以存在多個ENTRYPOINT指令,但是隻有最後一個會生效.
Dockerfile中如果既有CMD又有ENTRYPOINT,並且CMD是一個完整可執行命令,那麼誰在最後誰生效
5.2.4.14. ONBUILD
用來在Dockerfile中定義一個觸發器
語法:
ONBUILD <instruction>
Dockerfile用來構建鏡像文件,鏡像文件也可以當成是基礎鏡像被另外一個Dockerfile用作FROM指令的參數
在後面這個Dockerfile中的FROM指令在構建過程中被執行的時候,會觸發基礎鏡像裏面的ONBUILD指令
ONBUILD不能自我嵌套,ONBUILD不會觸發FROM和MAINTAINER指令
在ONBUILD指令中使用ADD和COPY要小心,因爲新構建過程中的上下文在缺少指定的源文件的時候會失敗
6. 本地鏡像發佈到阿里雲
有時候需要共享鏡像或者習慣使用自己定義的鏡像,可以註冊私有倉庫,國內推薦使用阿里雲
步驟:
1.登錄阿里雲容器鏡像服務:https://cr.console.aliyun.com/cn-hangzhou/repositories
2.將鏡像推送到阿里雲
# 登錄阿里雲的docker倉庫
$ sudo docker login --username=[用戶名] registry.cn-hangzhou.aliyuncs.com
# 創建指定鏡像的tag,歸入某個倉庫
$ sudo docker tag [鏡像ID] registry.cn-hangzhou.aliyuncs.com/user01/user01:[鏡像版本號]
# 講鏡像推送到倉庫
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/user01/user01:[鏡像版本號]
3.拉取鏡像
docker pull registry.cn-hangzhou.aliyuncs.com/coldest7/mytom:v1