生成自定義Docker映象
- 本文記錄生成自己的Docker映象的兩個例子。第一個是在一個SpringBoot工程基礎上生成映象,第二個是在普通的基於Tomcat的Web工程的基礎上生成映象。
Docker常用命令
列出所有映象(加上引數 -a
可以包括中間層映象,還有 -q
和 --format
等實用引數)
docker image ls
檢視映象、容器、資料卷所佔用的空間
docker system df
刪除映象
docker image rm [選項] <映象1> [<映象2> ...]
啟動映象
docker run [OPTIONS] <映象>
[OPTIONS]
常用引數:
-d
: 後臺執行容器,並返回容器ID;
-i
: 以互動模式執行容器,通常與 -t 同時使用;
-t
: 為容器重新分配一個偽輸入終端,通常與 -i 同時使用;
-p
: 埠對映,格式為:主機(宿主)埠:容器埠;
--name "xxx"
: 為容器指定一個名稱;
以互動式終端方式進入容器
docker exec -it <容器名>
使用 Dockerfile 建立映象,這個後面必須跟引數,且須有一個 .
docker build
生成SpringBoot的Web工程的映象
建立SpringBoot的工程
首先建立一個簡單的SpringBoot工程,工程很簡單,功能是訪問localhost:8080從而跳轉到指定頁面。工程中只有一個TestController,這個TestController的預設路徑指向index.html頁面,這個index.html在resources目錄下的templates.home中。static.home可以忽略,其中存的只是index.html的樣式檔案。
工程目錄結構如下:

SpringBoot工程目錄結構
TestController的內容,沒有任何邏輯,只是跳轉到index.html頁面:
package com.example.learndocker.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/") public class TestController { @RequestMapping(value = "") public String home() { return "home/index"; } }
為了返回頁面,需要引用模板引擎,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>learn-docker</artifactId> <version>0.0.1-SNAPSHOT</version> <name>learn-docker</name> <description>sth about docker</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.1.3.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
執行LearnDockerApplication的main方法,在瀏覽器訪問localhost:8080,可以看到如下頁面:

SpringBoot啟動後訪問localhost:8080
生成Docker映象
接下來生成docker映象。首先將SpringBoot打成jar包,然後在任意位置建立Dockerfile檔案,我是在learn-docker的工程目錄下建立的,為了方便,我直接在IDEA中編輯了。
添加了Dockerfile檔案,並且打包工程之後,工程目錄結構如下:

Dockerfile所在目錄

Dockerfile所在目錄
Dockerfile內容如下:
#docker倉庫的JDK映象 FROM java:8 #掛載點(根據需要可以不要),即容器中/tmp(這個目錄是springboot內嵌的Tomcat預設使用目錄)的改動會同步到主機的指定目錄 VOLUME /tmp #將自己的jar包加入生成的映象中(在JDK這一層的基礎上加上我們的jar構建新的映象) ADD target/learn-docker-0.0.1-SNAPSHOT.jar learn-docker.jar #容器啟動完執行 ENTRYPOINT ["java","-jar","learn-docker.jar"]
分析:執行springboot的web工程,需要作業系統+JDK/JRE,所以需要以作業系統映象作為基礎,然後加入JDK/JRE,再加上自己的jar,生成自定義映象。
但是因為Docker映象是分層構建,所以官方的java:8映象中已經包含了作業系統的映象這一層,所以此處直接引用此基礎映象即可。然後加入我們自己的jar,在基礎映象的基礎上生成新的映象。並設定當啟動容器時,啟動springboot的jar包即可。
當然,如果不想使用現有的Java映象,也可以下載好JDK/JRE,並以現有的作業系統的映象為基礎(有很多優化過的體積很小的作業系統基礎映象,比如alpine),加入JDK/JRE,同時加入我們自己的jar,配置好Java環境變數,生成新的映象,這樣會使得新映象的層數少一層,原則上是層數越少越好。
執行命令 docker build -t learndocker:v1 .
構建映象,注意命令後面有一個 .
不能少,構建過程:

映象構建過程
構建完畢之後:

構建映象完畢
此時 docker images
檢視映象,可以看到剛構建完的自己命名的learndocker:v1,當然同時也下載了java:8的映象(這裡可以看出分層構建映象的思想)。kafka映象是本人之前下載的。

檢視映象.jpg
此時可以正常啟動容器並將宿主的8080埠與映象的8080埠對映,執行命令 docker run -p 8080:8080 <映象id>
,此時我並沒有讓容器在後臺啟動,所以當我退出終端時,容器會停止。

啟動容器
保持終端不關閉,此時訪問瀏覽器localhost:8080,可以看到與之前同樣的頁面,整個定製映象並啟動的過程成功。
為了理解掛載點的意思,在啟動時使用 docker run -v /Users/shakeli/idea_workspace/learn-docker/test:/tmp -p 8080:8080 6b2bd203cc3f
來啟動,即使用-v引數加了宿主目錄與容器目錄的對映關係,那麼會在/Users/shakeli/idea_workspace/learn-docker/test的目錄下,同步容器中/tmp目錄中的內容(如果test目錄不存在會自動生成):

1552494286526.jpg
生成正常Web工程的Docker映象
經過上面的分析,我們可以分析如果只是正常的web工程,我們的Dockerfile最少需要哪些指令。由於springboot集成了Tomcat,而如果不用springboot,那麼我們需要加上Tomcat,理論上來說如果從0構建,那麼需要:作業系統+JDK/JRE+Tomcat。
由於JDK/JRE需要作業系統,而Tomcat又需要JDK/JRE,那麼如果我們以現有的官方映象為基礎,實際上只需要Tomcat的作為基礎映象即可,當然,如果不使用現有的Tomcat映象,而是以作業系統映象為基礎,加入JDK/JRE,加入Tomcat,會比使用現有Tomcat作為基礎映象少一層。
未完待續……
附Dockerfile常用指令
附Dockerfile的常用指令
FROM <image>:<tag>
指定基礎映象,必須在Dockerfile第一行
MAINTAINER <name>
指定維護者資訊
RUN <command>
在映象中要執行的命令
WORKDIR
:指定當前工作目錄,相當於 cd
EXPOSE <port> [<port>...]
指定容器要開啟的埠
ENV <key> <value>
或者 ENV <key>=<value> ...
指定一個/多個環境變數,會被後續 RUN 指令使用,並在容器執行時保持
ADD <src> <dest>
把檔案複製到映象中,src可以是連結
COPY <src>... <dest>
COPY的<src>只能是本地檔案,其他用法與ADD一致
CMD
或 ENTRYPOINT
容器啟動時執行的命令,兩者有些許區別,可以組合使用
ARG <name>[=<default value>]
設定變數
IDEADocker外掛
未完待續……