1. 程式人生 > >實戰Spring Boot 2.0系列(一)

實戰Spring Boot 2.0系列(一)

前言

通常我們使用 Dockerfile 來構建專案的 Docker 映象。但是也有使用 gradle 在編譯專案的時候一起把映象給 構建上傳 的需求。本文將會講解如何使用 gradle 編寫並配置 Dockerfile 並生成 映象

正文

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 外掛已經被上傳到 jCenterMavenCentral 上。所以只需要在 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 外掛會新增一個 distDockergradle 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。聲明瞭在 構建映象 是基於的 Imagemaintainer 相當於 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 資料夾下面會出現 Dockerfilespring-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 ApiDocker Hub 等用法,可以參考該專案的 GitHub 地址來進行配置使用:
https://github.com/Transmode/gradle-docker

歡迎關注技術公眾號: 零壹技術棧

零壹技術棧

本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。