为了账号安全,请及时绑定邮箱和手机立即绑定

实战Spring Boot 2.0系列(一) - 使用Gradle构建Docker镜像

前言

通常我们使用 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


本帐号将持续分享后端技术干货包括虚拟机基础多线程编程高性能框架异步、缓存和消息中间件分布式和微服务架构学习和进阶等学习资料和文章。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消