使用Gradle 构建SpringBoot应用的Docker镜像

栏目: Java · 发布时间: 5年前

内容简介:通过结合docker容器,目前我们应用的发布流程大致如下:我们的工程是:

通过结合 docker 容器,目前我们应用的发布流程大致如下:

使用Gradle 构建SpringBoot应用的Docker镜像

Gradle脚本构建镜像

我们的工程是:

  • 基于SpringBoot 2.0.3.RELEASE
  • 采用JDK8编译
  • gradle 构建

根据我们发布流程的要求,构建出最终的镜像需要满足几个目标:

  • 尽可能构建体积小的镜像
  • 通过执行简单的gradle命令,构建镜像并push到阿里云的dockerHub仓库
  • 构建的镜像版本,有唯一标识,方便发布。比如版本中含有日期和 最后一次git commit的hash值

我们最终选用了 https://github.com/bmuschko/gradle-docker-plugin 的gradle-docker-plugin来实现构建docker镜像。该插件支持 java-applicationspring-boot-application 两种方式,很明显我们选取spring-boot-applicaiton插件。

在原工程的build.gradle 最后加上:

apply from: 'docker.gradle'

在build.gradle的同一级目录下新建文件docker.gradle。

添加:

buildscript {
    repositories {

        mavenCentral()
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.bmuschko:gradle-docker-plugin:4.0.1'
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: DockerRemoteApiPlugin
apply plugin: com.bmuschko.gradle.docker.DockerSpringBootApplicationPlugin

都是一些基础配置。

def projectname = "${project.getName()}"
def dockerVer = getGitVersion()
def port = 8990

这里定义一些全局变量使用。port可以根据实际情况定义。其中 getGitVersion() 的定义:

import java.text.SimpleDateFormat
def getGitVersion() {
    def logTime = 'git log'.execute() | 'grep Date:'.execute() | 'head -n 1'.execute()
    logTime.waitFor()
    Date date = new Date(logTime.text.replace("Date:", "").trim())
    String pushTime = new SimpleDateFormat("yyyyMMddHHmmss").format(date)
    return pushTime + "." + ('git rev-parse --short HEAD'.execute().text.trim())
}

可以看到拼接了git仓库的最后一个commit 的提交时间和hash值。

gradle-docker-plugin 预定义了一些task,我们只需要简单配置:

docker { 
    url = getDefaultDockerUrl()
    registryCredentials {
        url = "registry.cn-hangzhou.aliyuncs.com"
        username = 'yourRepoUsername'
        password = 'yourRepopswd'
    }
    springBootApplication {
        baseImage = 'openjdk:8-alpine'
        ports = [port, port]
    }

}

getDefaultDockerUrl 是本地docker 的url,plugin对windows、 linux 、mac都已经有了相应实现。

registryCredentials 是docker Hub的认证信息配置。 阿里云的dockerHub配置如上。

springBootApplication 只需要配置 baseImage 和端口映射。可以看到我们基于 openjdk:8-alpine ,alpine linux 镜像只有4.4M,不过 openjdk:8-alpine 镜像体积赫然有103MB那么大了。

配置这些就可以构建镜像,但是有些小问题需要解决。

  1. openjdk:8-alpine` 默认是标准时区,而不是+8时区,需要修改。
  2. 该插件对私有docker仓库的tag支持存在bug,需要特殊处理。

接下来我们需要重写其中的 createDockerFile,buildImage,PushImage Task 来解决这两个问题。

其中 createDockerFile:

task createDockerfile(type: Dockerfile) {
    dependsOn dockerSyncArchive
    from(docker.springBootApplication.baseImage.get())
    copyFile(bootWar.archiveName, "/app/${bootWar.archiveName}".toString())
    //https://wiki.alpinelinux.org/wiki/Setting_the_timezone
    //https://github.com/gliderlabs/docker-alpine/issues/428
    runCommand(' echo \'http://mirrors.ustc.edu.cn/alpine/v3.8/main\' > /etc/apk/repositories  ' +
            ' && echo \'http://mirrors.ustc.edu.cn/alpine/v3.8/community\' >>/etc/apk/repositories  ' +
            ' && apk update && apk add tzdata  ' +
            ' && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  ' +
            ' && echo "Asia/Shanghai" > /etc/timezone  ' +
            ' && date '+
            ' && rm -rf /var/cache/apk/* ' +
            ' && rm -rf /usr/local/share/.cache')
    entryPoint("java")
    defaultCommand("-jar", "/app/${bootWar.archiveName}".toString())
    exposePort(docker.springBootApplication.ports)


}

上面主要是创建Dockerfile,编写指令来配置合适的 timezone 。使用中科大的apk安装源(mirrors.ustc.edu.cn)更快。。。

task buildImage(type: DockerBuildImage) {
    dependsOn createDockerfile
    inputDir = createDockerfile.destFile.get().asFile.parentFile
    tag = "zongwu233/${projectname}:${dockerVer}".toLowerCase()
}

//https://github.com/bmuschko/gradle-docker-plugin/issues/209
task dockerTag(type: com.bmuschko.gradle.docker.tasks.image.DockerTagImage) {
    dependsOn buildImage
    imageId = "zongwu233/${projectname}:${dockerVer}".toLowerCase()
    tag = "${dockerVer}".toLowerCase()
    repository = "registry.cn-hangzhou.aliyuncs.com/zongwu233/${projectname}".toLowerCase()
}

解决私有DockerHub 的tag问题。更详细的讨论见 https://github.com/bmuschko/gradle-docker-plugin/issues/209

其中 zongwu233 是在阿里云DockerHub中的命名空间, ${projectname} 是仓库名称。

最后是push task:

task pushImage(type: DockerPushImage) {
    dependsOn dockerTag
    imageName = "registry.cn-hangzhou.aliyuncs.com/zongwu233/${projectname}".toLowerCase()
}

另外要在createDockerFile,buildImage 等task之前 加上import 声明:

import com.bmuschko.gradle.docker.DockerRemoteApiPlugin
import com.bmuschko.gradle.docker.tasks.image.*
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerPushImage

这样,在控制台输入命令:

gradle pushImage

即可完成应用的docker镜像构建并且push到阿里云仓库。


以上所述就是小编给大家介绍的《使用Gradle 构建SpringBoot应用的Docker镜像》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code Reading

Code Reading

Diomidis Spinellis / Addison-Wesley Professional / 2003-06-06 / USD 64.99

This book is a unique and essential reference that focuses upon the reading and comprehension of existing software code. While code reading is an important task faced by the vast majority of students,......一起来看看 《Code Reading》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具