前言
通常我們使用 Dockerfile
來構建專案的 Docker
映象。但是也有使用 gradle
在編譯專案的時候一起把映象給 構建 並 上傳 的需求。本文將會講解如何使用 gradle
編寫並配置 Dockerfile
並生成 映象。
本系列文章
- 實戰Spring Boot 2.0系列(一) – 使用Gradle構建Docker映象
- 實戰Spring Boot 2.0系列(二) – 全域性異常處理和測試
- 實戰Spring Boot 2.0系列(三) – 使用@Async進行非同步呼叫詳解
- 實戰Spring Boot 2.0系列(四) – 使用WebAsyncTask處理非同步任務
- 實戰Spring Boot 2.0系列(五) – Listener, Servlet, Filter和Interceptor
- 實戰Spring Boot 2.0系列(六) – 單機定時任務的幾種實現
正文
1. 建立專案
利用 Spring Initializer
建立一個 gradle
專案 spring-boot-gradle-for-docker
,建立時新增一個 web
依賴。得到的初始 build.gradle
如下:
buildscript {
ext {
springBootVersion = `2.0.2.RELEASE`
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: `java`
apply plugin: `org.springframework.boot`
apply plugin: `io.spring.dependency-management`
group = `io.ostenant.springboot.sample`
version = `1.0`
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile(`org.springframework.boot:spring-boot-starter-web`)
testCompile(`org.springframework.boot:spring-boot-starter-test`)
}
複製程式碼
2. 配置入口類
為了方便容器部署的測試,在 Spring Boot
啟動類上配置一個控制器,響應當前的系統時間。
@RestController
@SpringBootApplication
public class Application {
private ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"));
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping("/")
public String retrieveTime() {
return threadLocal.get().format(new Date());
}
}
複製程式碼
3. 新增外掛
這裡使用 gradle-docker
外掛 來實現 docker
映象構建。這樣,我們就可以直接在 Gradle
的指令碼里配置 Dockerfile
達到 構建映象 功能的目的。
gradle-docker
外掛已經被上傳到 jCenter
和 MavenCentral
上。所以只需要在 dependencies
新增依賴 se.transmode.gradle:gradle-docker:1.2
就能使用 docker
外掛。
buildscript {
ext {
springBootVersion = `2.0.2.RELEASE`
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("se.transmode.gradle:gradle-docker:1.2")
}
}
複製程式碼
4. 應用外掛
新增以下程式碼到 build.gradle
中
apply plugin: `application`
apply plugin: `docker`
複製程式碼
如果新增了 application
外掛的話,預設 gradle-docker
外掛會新增一個 distDocker
的 gradle task
,用來構建一個 包含所有程式檔案 的 docker
映象。
5. 配置映象構建資訊
5.1. 配置group
group = `io.ostenant.springboot.sample`
複製程式碼
5.2. 配置映象名稱和版本號
jar {
baseName = "spring-boot-gradle-for-docker"
version = 1.0
}
複製程式碼
其中映象的 tag
預設的構成為:專案組/應用名稱:版本號
tag = "${project.group}/${applicationName}:${tagVersion}"
複製程式碼
-
project.group:標準的
gradle
屬性,如果不進行定義,外掛預設會 省略${project.group}
這個屬性。 -
applicationName:應用被容器化時的 名稱。
-
tagVersion:可選屬性,會作為映象的 標籤。預設值為
project.version
,如果未指定project.version
,則使用latest
作為標記。
5.3. 配置docker構建基礎資訊
distDocker {
baseImage = "openjdk"
maintainer = "harrison"
}
複製程式碼
其中,baseImage
相當於 Dockerfile
中宣告的 FROM
。宣告瞭在 構建映象 是基於的 Image
,maintainer
相當於 MAINTAINER
,宣告瞭 映象作者。如果宣告瞭 registry
地址,外掛在 映象射生成後 可以自動 push
到該地址。其他的配置還包括 docker hub
的 地址、使用者名稱 和 密碼。
更詳細的配置案例如下:
docker {
baseImage `openjdk`
maintainer `harrison`
useApi true
hostUrl `http://myserver:4243`
apiUsername `user`
apiPassword `password`
apiEmail `me@mycompany.com`
}
複製程式碼
6. 新增task任務
完成了基本的配置,我們還需要新增一個 task
用來在 gradle
編譯的時候 執行映象構建。
外掛提供了一些 轉換方法,用來指代 Dockerfile
中的 關鍵詞語法,如下表,可以按照需求對照著來:
Dockerfile關鍵詞 | gradle task方法 |
---|---|
ADD | addFile(Closure copySpec) |
addFile(String source, String dest) | |
addFile(File source, String dest) | |
CMD | defaultCommand(List cmd) |
ENTRYPOINT | entryPoint(List entryPoint) |
ENV | setEnvironment(String key, String val) |
EXPOSE | exposePort(Integer port) |
exposePort(String port) | |
RUN | runCommand(String cmd) |
USER | switchUser(String userNameOrUid) |
VOLUME | volume(String… paths) |
WORKDIR | workingDir(String dir) |
下面是本專案的 taskBuilder
的任務配置
task dockerBuilder(type: Docker) {
applicationName = jar.baseName
tagVersion = jar.version
volume(`/tmp`)
addFile("${jar.baseName}-${jar.version}.jar", "app.jar")
entryPoint(["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", `app.jar`])
exposePort(8080)
doFirst {
copy {
from jar
into stageDir
}
}
}
複製程式碼
構建完成y以後,專案根目錄的 build/docker
資料夾下面會出現 Dockerfile
和 spring-boot-gradle-for-docker-1.0.jar
檔案。其中,以上的 task
等同於以下的 Dockerfile
。
FROM aglover/java8-pier
VOLUME ["/tmp"]
ADD spring-boot-gradle-for-docker-1.0.jar app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
EXPOSE 8080
複製程式碼
如果覺的在 task
中編寫 Dockerfile
替換指令碼 非常彆扭,也可以直接在 task
中指定 Dockfile
的 檔案路徑,直接使用已有的檔案來生成映象:
task buildDocker(type: Docker) {
applicationName = jar.baseName
tagVersion = jar.version
dockerfile = file(`Dockerfile`)
doFirst {
copy {
from jar
into stageDir
}
}
}
複製程式碼
通過 file()
指定 task
使用位於 專案根目錄 的 Dockerfile
來生產映象。
7. 編譯並構建Docker映象
進入專案根目錄,執行 gradle
命令進行打包構建。
$ ./gradlew clean build dockerBuilder --info
複製程式碼
gradle
首先會執行 本地測試,然後進行 專案打包,進一步根據 docker-gradle
外掛進行 映象構建。
等待出現 BUILD SUCCESSFUL
就表明任務執行成功。可以觀察到映象的名稱為
io.ostenant.springboot.sample/spring-boot-gradle-for-docker:1.0
複製程式碼
執行 docker images
檢視本地映象,進一步驗證映象構建成功。
下面給出 build.gradle
完整的 配置檔案
buildscript {
ext {
springBootVersion = `2.0.2.RELEASE`
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("se.transmode.gradle:gradle-docker:1.2")
}
}
apply plugin: `java`
apply plugin: `org.springframework.boot`
apply plugin: `io.spring.dependency-management`
apply plugin: `application`
apply plugin: `docker`
group = `io.ostenant.springboot.sample`
version = `1.0`
sourceCompatibility = 1.8
targetCompatibility = 1.8
mainClassName = "io.ostenant.springboot.sample.Application"
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile(`org.springframework.boot:spring-boot-starter-web`)
testCompile(`org.springframework.boot:spring-boot-starter-test`)
}
jar {
baseName `spring-boot-gradle-for-docker`
version `1.0`
}
distDocker {
baseImage `openjdk`
maintainer `harrison`
}
task dockerBuilder(type: Docker) {
applicationName = jar.baseName
tagVersion = jar.version
volume(`/tmp`)
addFile("${jar.baseName}-${jar.version}.jar", "app.jar")
entryPoint(["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", `app.jar`])
exposePort(8080)
doFirst {
copy {
from jar
into stageDir
}
}
}
複製程式碼
8. 使用映象啟動容器
執行如下命令,根據映象啟動容器,對外暴露 8080
訪問埠。
$ docker run -d --name gradle-boot -p 8080:8080 io.ostenant.springboot.sample/spring-boot-gradle-for-docker:1.0
複製程式碼
訪問 http://127.0.0.1:8080/
,頁面會輸出當前系統時間,如圖所示:
小結
gradle-docker
外掛還提供了配置 映象倉庫地址、配置使用 Docker Remote Api
和 Docker Hub
等用法,可以參考該專案的 GitHub
地址來進行配置使用:
github.com/Transmode/g…。
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。