1 What & Why
What: 什么是構建docker鏡像?
構建docker鏡像在現有鏡像的基礎上,修改或添加個人的功能后,重新打包成新鏡像的過程
Why: 為什么要構建docker鏡像?
docker鏡像方便部署及分享他人
2 Hello World
2.1 目標
- 利用現有鏡像ubuntu構建新鏡像
- 鏡像的功能是利用ubuntu的echo命令打印Hello world
2.2 創建文件夾
mkdir demo01-helloworld
cd demo01-helloworld
2.3 創建配置文件
Docker以文件Dockerfile
作為配置文件,內容如下
Dockerfile
FROM ubuntu:latest
CMD ["/bin/echo", "Hello world!"]
以上內容非常簡單
FROM
用來配置基礎鏡像,這里以ubuntu的最新版本的鏡像作為基礎鏡像CMD
表示鏡像中執行的命令,這里等同於執行命令/bin/echo "Hello World!"
- 當前的格式為Exec格式
- 后面會介紹shell格式
2.4 構建鏡像
命令
docker image build . -t demo01-helloworld:0.0.1
-
.
表示當前文件夾里的所有文件 -
-t
等同於--tag
,作用是給鏡像打標簽,這里的標簽名為demo01-helloworld
-
:
后是鏡像的版本號,如果省略則默認為latest
構建過程如下,當打印Successfully tagged demo01-helloworld:0.0.1
表明鏡像構建成功
$ docker image build . -t demo01-helloworld
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM ubuntu:latest
---> 4e2eef94cd6b
Step 2/2 : CMD ["/bin/echo", "Hello world!"]
---> Running in 581995f3af46
Removing intermediate container 581995f3af46
---> afa0f6e8fc94
Successfully built afa0f6e8fc94
Successfully tagged demo01-helloworld:0.0.1
可以用命令docker image ls
查詢所有鏡像,再次確認已經構建完成
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
demo01-helloworld 0.0.1 afa0f6e8fc94 19 seconds ago 73.9MB
運行鏡像,先生成容器,再啟動容器
$ docker container run demo01-helloworld:0.0.1
Hello world!
docker啟動時先判斷有沒有該容器,如果不存在則通過鏡像創建相應的容器,然后執行容器
2.5 注意
需要說明的是CMD
可以在構造鏡像的時候不指定,啟動容器的時候執行。如果啟動時指定了命令,則CMD
中指定的命令將不會執行,即被覆蓋,現象如下。你看懂了嗎?
$ docker container run demo01-helloworld:0.0.1 /bin/echo "Hello world! v2"
Hello world! v2
3 java應用
3.1 目標
- 利用現有鏡像openjdk構建新鏡像
- 鏡像的功能是運行java程序打印Hello java
3.2 創建文件夾
mkdir demo02-hellojava
cd demo02-java
3.3 創建java工程
選擇你喜歡的方式創建一個maven工程,可以從通過網頁下載模板,可以利用eclipse和idea等等
這里采用mvn命令的方式創建
mvn archetype:generate -DgroupId=org.zwx.hellojava -DartifactId=demo02-hellojava -DinteractiveMode=false
結果如下
$ mvn archetype:generate -DgroupId=org.zwx.hellojava -DartifactId=demo02-hellojava -DinteractiveMode=false
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] ...省略一些內容
[INFO] Parameter: basedir, Value: /Users/zhouweixin/docker-demos
[INFO] Parameter: package, Value: org.zwx.hellojava
[INFO] Parameter: groupId, Value: org.zwx.hellojava
[INFO] Parameter: artifactId, Value: demo02-hellojava
[INFO] Parameter: packageName, Value: org.zwx.hellojava
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/zhouweixin/docker-demos/demo02-hellojava
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.557 s
[INFO] Finished at: 2020-09-28T17:55:09+08:00
[INFO] ------------------------------------------------------------------------
文件目錄
.
├── pom.xml
└── src
├── main
│ └── java
│ └── org
│ └── zwx
│ └── hellojava
│ └── App.java
└── test
└── java
└── org
└── zwx
└── hellojava
└── AppTest.java
3.4 編譯執行
在打包之前先確定java應用可以正常執行
首先,修改文件src/main/java/org/zwx/hellojava/App.java
package org.zwx.hellojava;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello java!" );
}
}
然后,用mvn
命令編譯打包
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< org.zwx.hellojava:demo02-hellojava >-----------------
[INFO] Building demo02-hellojava 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ...省略一些內容
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ demo02-hellojava ---
[INFO] Building jar: /Users/zhouweixin/docker-demos/demo02-hellojava/target/demo02-hellojava-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.531 s
[INFO] Finished at: 2020-09-28T17:59:40+08:00
[INFO] ------------------------------------------------------------------------
文件目錄
.
├── pom.xml
├── src
│ └── ...省略一些內容
└── target
├── demo02-hellojava-1.0-SNAPSHOT.jar
└── ...省略一些內容
當你執行完命令mvn package
后,首先會編譯生成一些class文件,然后打包成demo02-hellojava-1.0-SNAPSHOT.jar
,生成的文件都在目錄target下
該jar文件是執行文件,具體執行命令如下
$ java -cp target/demo02-hellojava-1.0-SNAPSHOT.jar org.zwx.hellojava.App
Hello java!
3.5 拉取基礎鏡像
如前文所述構建鏡像需要一個基礎鏡像,基礎鏡像也可以不提前拉取,構建的時候如果不存在也會自動拉取
該例子中要想啟動java應用,你知道需要哪個環境嗎?
你應該是猜對了,僅僅需要java的運行時環境(jre)
首先到hub.docker.com上檢索jre的相關tag,這里我們選擇的是8u265-jre
二話不說,先拉取鏡像(也可以不提前拉取)
$ docker pull openjdk:8u265-jre
8u265-jre: Pulling from library/openjdk
57df1a1f1ad8: Pull complete
71e126169501: Pull complete
1af28a55c3f3: Pull complete
a9777c2d5c29: Pull complete
9248106993db: Pull complete
1f74ab5b5b3e: Pull complete
Digest: sha256:e98dece4606dc1ec47c0c9ab6aa43931577232a5b7d6fd46f3ead7377727b412
Status: Downloaded newer image for openjdk:8u265-jre
docker.io/library/openjdk:8u265-jre
用交互的方式運行該鏡像並確定java的版本
$ docker container run -it openjdk:8u265-jre
root@0687c67dccd0:/# java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)
參數說明
-it
是-i
和-t
的縮寫-i
全稱是--interactive
,即交互模式,可以正常的輸入輸出-t
是一個偽TTY,即偽終端
3.6 構建鏡像
創建配置文件Dockerfile
FROM openjdk:8u265-jre
COPY target/demo02-hellojava-1.0-SNAPSHOT.jar /usr/src/demo02-hellojava-1.0-SNAPSHOT.jar
CMD java -cp /usr/src/demo02-hellojava-1.0-SNAPSHOT.jar org.zwx.hellojava.App
參數說明
COPY
命令用於將本地文件拷貝到基礎鏡像中,並且這個基礎鏡像中有java運行時環境,兩者結合滿足正常運行程序- 第一個參數為本地文件目錄
- 第二個參數為基礎鏡像中的目錄
CMD
命令表示在基礎鏡像中執行的命令(可以不寫數組的形式)
執行鏡像構建命令
$ docker image build . -t demo02-hellojava:0.0.1
Sending build context to Docker daemon 38.91kB
Step 1/3 : FROM openjdk:8u265-jre
---> d9d1d3243082
Step 2/3 : COPY target/demo02-hellojava-1.0-SNAPSHOT.jar /usr/src/demo02-hellojava-1.0-SNAPSHOT.jar
---> Using cache
---> 6c34d345bb51
Step 3/3 : CMD java -cp /usr/src/demo02-hellojava-1.0-SNAPSHOT.jar org.zwx.hellojava.App
---> Running in 0d9a33ea0ae1
Removing intermediate container 0d9a33ea0ae1
---> fc3cd9ee5218
Successfully built fc3cd9ee5218
Successfully tagged demo02-hellojava:0.0.1
啟動
$ docker container run demo02-hellojava:0.0.1
Hello java!
4 Dockfile中的命令
命令 | 功能 |
---|---|
FROM | 指定基礎鏡像 |
COPY | 復制文件或文件夾 |
ENV | 設置環境變量 |
RUN | 執行一個命令,可以寫多個,通常用於安裝軟件包 |
CMD | 執行一個命令,只有一個被執行,可被docker run后面的命令所覆蓋,即如果命令行中有該命令,CMD中的將不會執行 |
ENTRYPOINT | 配置容器啟動時的命令,一定會執行 |
EXPOSE | 暴露的端口號 |