通常我们使用 Dockerfile
来构建项目的 Docker
镜像。但是也有使用 gradle
在编译项目的时候一起把镜像给 构建 并 上传 的需求。本文将会讲解如何使用 gradle
编写并配置 Dockerfile
并生成 镜像。
利用 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')
}
复制代码
为了方便容器部署的测试,在 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());
}
}
复制代码
这里使用 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")
}
}
复制代码
添加以下代码到 build.gradle
中
apply plugin: 'application'
apply plugin: 'docker'
复制代码
如果添加了 application
插件的话,默认 gradle-docker
插件会添加一个 distDocker
的 gradle task
,用来构建一个 包含所有程序文件 的 docker
镜像。
group = 'io.ostenant.springboot.sample'
复制代码
jar {
baseName = "spring-boot-gradle-for-docker"
version = 1.0
}
复制代码
其中镜像的 tag
默认的构成为:项目组/应用名称:版本号
tag = "${project.group}/${applicationName}:${tagVersion}"
复制代码
gradle
属性,如果不进行定义,插件默认会 省略 ${project.group}
这个属性。project.version
,如果未指定 project.version
,则使用 latest
作为标记。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'
}
复制代码
完成了基本的配置,我们还需要添加一个 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
来生产镜像。
进入项目根目录,运行 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
}
}
}
复制代码
运行如下命令,根据镜像启动容器,对外暴露 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…。
欢迎关注技术公众号: 零壹技术栈
本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。
Original url: Access
Created at: 2019-05-29 15:25:43
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论