实战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
插件已经被上传到 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
地址来进行配置使用
https://github.com/Transmode/gradle-docker。
本帐号将持续分享后端技术干货包括虚拟机基础多线程编程高性能框架异步、缓存和消息中间件分布式和微服务架构学习和进阶等学习资料和文章。
共同学习,写下你的评论
评论加载中...
作者其他优质文章