使用gradle構(gòu)建springboot多模塊項目,并構(gòu)建成docker容器的demo.
基礎(chǔ)環(huán)境
- gradle(4+)
- java(8+) PS:最好還是使用jdk8,因為9之后發(fā)生了一些變化,比如刪除了一些包.
- docker(可選)
構(gòu)建過程
!!! 構(gòu)建過程建立在已經(jīng)安裝了基礎(chǔ)環(huán)境的條件之上.
1.創(chuàng)建項目根目錄,此處項目名稱為:java-springboot-gradle-docker
mkdir java-springboot-gradle-docker && cd java-springboot-gradle-docker
上面的命令將會創(chuàng)建一個java-springboot-gradle-docker目錄,并進入該目錄下,此處可以替換為自己想要的跟項目名稱.
這里建立的目錄,將會作為多模塊項目的頂層項目存在.
2.初始化為gradle項目
gradle init
gradle的init任務(wù),通常用來生成gradle項目的基礎(chǔ)結(jié)構(gòu),可以通過type來指定生成gradle項目的類型,這里不指定的目的是為了完全自己一步步構(gòu)造完整的目錄結(jié)構(gòu).
在實際使用過程中可以根據(jù)自己的需要選擇類型,比如java-application.
在不指定type的前提下,該命令將會在目錄下生成以下基礎(chǔ)文件:
build.gradle
gradle
gradlew
gradlew.bat
settings.gradle
build.gradle是項目構(gòu)建文件,也是接下來會主要修改的文件,我們將會通過修改該文件來實現(xiàn)插件和依賴的版本管理等功能.
gradle是一個目錄,主要包含了gradle的包裝器,他和gradlew,gradlew.bat文件一起,主要作用就是可以讓用戶在不安裝gradle的情況下,
依然可以使用gradle提供的功能.
settings.gradle則主要用來在多模塊的時候?qū)崿F(xiàn)管理子模塊的功能.
3.編寫gradle.properties文件.
在跟項目目錄下執(zhí)行下列命令來生成gradle.properties文件.
echo "#Gradle資源文件
#指定當(dāng)前項目的JDK(適用于不使用系統(tǒng)環(huán)境變量對應(yīng)的JDK)
org.gradle.java.home=/usr/local/java8
#啟用并行編譯
org.gradle.parallel=true
#啟用編譯守護進程
org.gradle.daemon=true
#配置可用編譯內(nèi)存
org.gradle.jvmargs=-Xms256m -Xmx1024m">>gradle.properties
gradle.properties文件的主要作用是為gradle在運行期間提供一些參數(shù),下面是這次使用的參數(shù)及其作用.
#Gradle資源文件
#指定當(dāng)前項目的JDK(適用于不使用系統(tǒng)環(huán)境變量對應(yīng)的JDK)
org.gradle.java.home=/usr/local/java8
#啟用并行編譯
org.gradle.parallel=true
#啟用編譯守護進程
org.gradle.daemon=true
#配置可用編譯內(nèi)存
org.gradle.jvmargs=-Xms256m -Xmx1024m
需要注意的是,上面的參數(shù)可以根據(jù)自己的需求來改變.
參數(shù)org.gradle.java.home參數(shù),需要修改為自己的JAVA_HOME路徑,否則將會報錯.
如果當(dāng)前已經(jīng)配置了JAVA環(huán)境變量的話,可以將該配置注釋掉.
4.創(chuàng)建一個新的目錄,并修改其為一個子模塊項目.
創(chuàng)建一個目錄.這次創(chuàng)建的目錄將會作為多模塊的子模塊項目出現(xiàn),這里建立一個eureka-demo
子模塊.
mkdir eureka-demo
修改settings.gradle文件,將eureka-demo作為子模塊.
echo "include 'eureka-demo'" >>settings.gradle
settings.gradle文件的include屬性,定義了當(dāng)前gradle項目包含的子模塊,如果有多個子模塊,可以使用多個include的形式來配置.
5.新建一個用戶自定義參數(shù)的配置文件(可選).
這一步,并不是必須的,如果需要跳過這一步,可以將本來應(yīng)該保存在該文件的數(shù)據(jù),放到build.gradle中的buildscript代碼塊中即可.
在本項目中,不會使用到buildscript代碼塊,但是需要知道的是,buildscript代碼塊主要是用來聲明gradle腳本本身需要使用的資源,而在其他地方直接聲明的配置,
將會作用在項目中.
為了盡可能的將數(shù)據(jù)模塊化,簡潔化,所以這里新建一個文件用來存放依賴jar包的版本和一些通用的參數(shù)配置.
首先,在項目根目錄下新建一個目錄gradle(此時該目錄應(yīng)該是已經(jīng)存在的,如果已經(jīng)存在不需要新建).
mkdir gradle
進入gradle目錄下,新建一個dependency.gradle文件,并輸入以下內(nèi)容:
/**
* ===================================================================================================================
* ------------------------------------------- 統(tǒng)一資源版本控制 ----------------------------------------------
* ===================================================================================================================
*/
def version = [
JDK : JavaVersion.VERSION_1_8, //JDK
]
//統(tǒng)一文件編碼控制
def encoding = [
OPTIONS: 'UTF-8'
]
//暴露參數(shù)
ext.custom = [
version : version,
encoding: encoding,
]
6.修改build.gradle文件,構(gòu)建項目的公共配置.
因為接下來的操作涉及到的內(nèi)容比較多,所以采用文本編輯器的形式來編輯(比如:vim).
接下來的步驟會在build.gradle文件插入大量的數(shù)據(jù),如果找不到應(yīng)該插入的位置,可以在本文的底部查看該實例項目的開源地址
,或者查看底部的完整配置文件內(nèi)容.
我們首先刪除掉build.gradle文件內(nèi)的所有內(nèi)容,因為其本身生成的文件內(nèi)部只是添加了一個測試依賴而已,并不是必須的.
我們首先需要引入一些通用的插件.
所以在build.gradle文件中中輸入下面的內(nèi)容.
configure(allprojects) { project ->
//項目基礎(chǔ)屬性
group 'cn.jpanda' //項目所屬組織
version '1.0-SNAPSHOT' //項目版本號
//引入插件
apply plugin: 'java' //java插件
apply plugin: 'maven' //maven插件
apply plugin: 'idea' //IDEA插件
apply plugin: 'eclipse' //eclipse插件
apply from: "${rootProject.rootDir}/gradle/dependency.gradle" //引入jar包版本配置文件
//JDK版本聲明
sourceCompatibility = custom.version.JDK
targetCompatibility = custom.version.JDK
//配置倉庫
repositories {
mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'https://repo.spring.io/libs-snapshot' }
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
mavenCentral()
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
//指定項目編碼
tasks.withType(JavaCompile) {
options.encoding = "${custom.encoding.OPTIONS}"
}
}
configure(allprojects) { project ->}表示內(nèi)部的配置將會應(yīng)用于所有的項目,在下面還會出現(xiàn)configure(subprojects){},其表示
配置的數(shù)據(jù)將會應(yīng)用在所有的子項目內(nèi),兩者的區(qū)別主要就是allprojects和subprojects.
在這里主要進行了項目的一些公共配置,比如項目共用的插件以及倉庫等配置.
上面沒有涉及太多的東西,具體的代碼作用已經(jīng)標(biāo)注上了注釋.
7.添加gradle包裝器(可選).
添加gradle wrapper可以統(tǒng)一開發(fā)使用gradle的版本,
避免在開發(fā)過程中因為gradle版本不一致而引發(fā)的問題.
在build.gradle文件的底部,加入代碼:
/**
* 生成gradlew文件,統(tǒng)一gradle版本,避免因為版本不同產(chǎn)生的問題
*/
task wrapper(type: Wrapper) {
gradleVersion = "4.8" //這里的版本根據(jù)自己的需求變更.
}
之后我們通過gradle wrapper命令就可以生成gradlew和gradlew.cmd文件了.
PS:雖然我們在執(zhí)行g(shù)radle init的時候已經(jīng)生成了該文件,但是默認生成的文件是我們自己電腦gradle版本的包裝器,所以如果需要使用不同的版本,
最好還是執(zhí)行這一步.
8.引入jar包依賴管理插件.
在使用maven進行構(gòu)建的項目的時候,我們通常會使用dependencyManagement標(biāo)簽統(tǒng)一管理所有項目的依賴,來盡量避免jar包沖突的問題.
這里spring boot同樣提供了org.springframework.boot插件
來在gradle中實現(xiàn)類似的功能.
引入該插件,需要在build.gradle中的開始部分輸入以下內(nèi)容:
plugins {
id 'org.springframework.boot' version '2.0.1.RELEASE' //spring提供的spring boot插件,主要用到了其依賴管理的功能.
}
需要注意的是,在build.gradle文件中,buildscript塊和plugin塊必須作為前兩個塊存在,否則會報錯的.
然后在configure(allprojects) { project ->...}代碼塊的apply代碼區(qū)域新增:
apply plugin: 'org.springframework.boot' //spring boot插件
apply plugin: 'io.spring.dependency-management' //實現(xiàn)maven的依賴統(tǒng)一管理功能
并在頂部添加:
import org.springframework.boot.gradle.plugin.SpringBootPlugin
這樣,我們就引入了org.springframework.boot插件,接下來就是使用該插件完成依賴管理的功能.
首先完成基礎(chǔ)配置,在包含了apply代碼的configure(allprojects){ project -> ...}代碼塊的底部,加入下面代碼,其作用主要是用來配置構(gòu)建jar包時的一些操作,
bootJar則類似于在maven中springboot插件的repackage功能.
jar {
enabled = true
}
bootJar {
launchScript()
archiveName = "${project.group}_${project.name}_${project.version}.jar"
}
9.添加使用的jar包的版本.
如果省略掉了步驟5,那么這一步的操作,同樣應(yīng)該放在buildscript代碼塊中的相應(yīng)位置.
這一步需要修改 項目根目錄/gradle/dependency.gradle文件.
主要是添加 def version=[...]中的數(shù)據(jù),修改后,該文件的內(nèi)容應(yīng)該如下:
/**
* ===================================================================================================================
* ------------------------------------------- 統(tǒng)一資源版本控制 ----------------------------------------------
* ===================================================================================================================
*/
def version = [
JDK : JavaVersion.VERSION_1_8, //JDK
JDBC : '6.0.6', //JDBC
SPRING_BOOT : '2.0.1.RELEASE', //spring boot 全家桶版本
SPRING_BOOT_MODELMAPPER: '1.1.0', //對象映射工具modelMapper
SPRING_BOOT_MYBATIS : '1.3.2', //mybatis-spring-boot
SPRING_BOOT_DRUID : '1.1.9', //druid和spring-boot整合包
SPRING_CLOUD : 'Finchley.RELEASE', //spring cloud全家桶
ALI_DRUID : '1.1.9', //阿里巴巴druid
ALI_FASTJSON : '1.2.47', //阿里巴巴fastJson
PAGEHELPER : '1.2.3', //分頁插件
APACHE_COMMON_LANG3 : '3.4', //apache common lang3
APACHE_COMMON_IO : '2.6', //Apache Commons IO庫包含實用程序類,流實現(xiàn),文件過濾器,文件比較器,endian轉(zhuǎn)換類等等.
]
//統(tǒng)一文件編碼控制
def encoding = [
OPTIONS: 'UTF-8'
]
//暴露參數(shù)
ext.custom = [
version : version,
encoding: encoding,
]
上面的文件中引入了一些常用的插件,但是本文目前不會涉及到這么多的插件.
10.使用插件進行依賴jar包版本的控制.
在build.gradle文件的底部或者task wrapper(type: Wrapper) {...}的上方輸入以下內(nèi)容:
/**
* ===================================================================================================================
* ------------------------------------------- 所有子項目的通用配置 ---------------------------------------------
* ===================================================================================================================
*/
configure(subprojects) {
project ->
dependencyManagement {
overriddenByDependencies = false
dependencies {
imports {
/**
* 通過依賴spring boot dependencies來取代繼承spring-boot-starter-parent,
* 該配置可以省略.
*/
mavenBom SpringBootPlugin.BOM_COORDINATES
/**
* 通過依賴spring cloud dependencies 來統(tǒng)一管理spring cloud 的版本
*/
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${custom.version.SPRING_CLOUD}"
}
/**
* mybatis-spring-boot整合包,該項目必須采用dependency來管理版本,而不能使用mavenBom,
* 使用mavenBom可能會導(dǎo)致其依賴的jar包和spring依賴的版本發(fā)生沖突.
*/
dependency "org.mybatis.spring.boot:mybatis-spring-boot-starter:${custom.version.SPRING_BOOT_MYBATIS}"
/**
* 阿里巴巴druid數(shù)據(jù)庫連接池
*/
dependency "com.alibaba:druid:${custom.version.ALI_DRUID}"
/**
* fastJson https://mvnrepository.com/artifact/com.alibaba/fastjson
*/
dependency "com.alibaba:fastjson:${custom.version.ALI_FASTJSON}"
/**
* druid數(shù)據(jù)庫連接池和spring-boot整合包
*/
dependency "com.alibaba:druid-spring-boot-starter:${custom.version.SPRING_BOOT_DRUID}"
/**
* 分頁插件
*/
dependency "com.github.pagehelper:pagehelper-spring-boot-starter:${custom.version.PAGEHELPER}"
/**
* 對象實體轉(zhuǎn)換工具包
*/
dependency "com.github.jmnarloch:modelmapper-spring-boot-starter:${custom.version.SPRING_BOOT_MODELMAPPER}"
/**
* Apache Commons IO庫包含實用程序類,流實現(xiàn),文件過濾器,文件比較器,endian轉(zhuǎn)換類等等.
*/
dependency "commons-io:commons-io:${custom.version.APACHE_COMMON_IO}"
}
}
}
這里是使用configure(subprojects) {}還是configure(allprojects) {},取決于父項目是否需要使用這些jar包.
本文中的父項目不需要使用jar包,所以這里采用了subprojects.
這一部分內(nèi)容,為所有的子模塊都添加了依賴版本控制的功能,其功能類似與maven的dependencyManagement.
這里需要注意的是 mavenBom和dependency的用法,如果錯誤的使用了mavenBom或許將會導(dǎo)致jar包沖突,我之前剛開始使用時錯誤的將
mybatis-spring-boot使用了mavenBom標(biāo)簽而導(dǎo)致了jar包沖突,這里應(yīng)該對maven中type為pom類型的文件使用mavenBom.
如果項目報錯找不到SpringAppcationBuilder的init方法,八成就是這兒出了問題.
編寫到這里,已經(jīng)完成了對依賴jar包的版本管理,接下來是為項目實際引入jar包.
11.為子項目引入公共jar依賴.
在build.gradle文件的底部或者task wrapper(type: Wrapper) {...}的上方輸入以下內(nèi)容:
configure(subprojects) {
project ->
/**
* -============================================================================================================
* -=====================================此處存放業(yè)務(wù)模塊的公共依賴==================================================
* -============================================================================================================
*/
dependencies {
/**
* -=================================================================================-
* - ******************** [運維]性質(zhì)相關(guān)依賴 *************************** -
* -=================================================================================-
*/
//服務(wù)監(jiān)控中心
compile 'org.springframework.boot:spring-boot-actuator'
//eureka注冊客戶端
compile 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
//全局統(tǒng)一配置中心
compile 'org.springframework.cloud:spring-cloud-starter-config'
//ribbon負載均衡依賴
compile 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon'
//spring cloud openfeign依賴,原feign已經(jīng)棄用,簡化調(diào)用方式
compile 'org.springframework.cloud:spring-cloud-starter-openfeign'
//spring cloud hystrix 保護模塊
compile 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'
/**
* -=================================================================================-
* - ******************** [工具/功能]性質(zhì)相關(guān)依賴 *************************** -
* -=================================================================================-
*/
//Json處理工具
compile 'com.alibaba:fastjson'
// Apache Commons IO庫包含實用程序類,流實現(xiàn),文件過濾器,文件比較器,endian轉(zhuǎn)換類等等.
compile 'commons-io:commons-io'
//使用lombok來簡化掉編碼過程中的通用的方法.
compile 'org.projectlombok:lombok'
//對象映射工具modelMapper
compile 'com.github.jmnarloch:modelmapper-spring-boot-starter'
//spring boot安全依賴
compile 'org.springframework.boot:spring-boot-starter-security'
//自定義配置管理
compile 'org.springframework.boot:spring-boot-configuration-processor'
/**
* -=================================================================================-
* - ******************** [數(shù)據(jù)庫]性質(zhì)相關(guān)依賴 *************************** -
* -=================================================================================-
*/
//阿里巴巴druid數(shù)據(jù)庫連接池
compile 'com.alibaba:druid'
//jdbc相關(guān)配置
runtime 'mysql:mysql-connector-java'
// druid數(shù)據(jù)庫連接池和spring-boot整合包
compile 'com.alibaba:druid-spring-boot-starter'
//mybatis-spring-boot整合包
compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter'
//分頁插件
compile 'com.github.pagehelper:pagehelper-spring-boot-starter'
//測試依賴
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
}
此時,就完成了項目的公共依賴的配置.
12.為子項目引入獨有的依賴.
在項目中,除去公共依賴,不同的項目可能會依賴一些特殊的jar包,而這些jar文件又不是共用的,沒有必要所有項目都引入,所以就會出現(xiàn)需要單獨為每個項目引入jar
包的場景.
針對這種場景,其實有很多種方法來實現(xiàn),這里我選擇的是在子項目的build.gradle文件中配置相關(guān)依賴.
進入子項目目錄中,并寫入依賴配置,此處寫入的是eureka的服務(wù)端依賴.
cd eureka-demo
echo "dependencies {
compile 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
}
">build.gradle
13.屏蔽父項目的構(gòu)建jar包功能.
因為父項目不提供具體的業(yè)務(wù),所以也就不需要打成jar包了,在父項目/build.gradle的底部加入下列代碼.
/**
* 關(guān)閉父項目的打包功能
*/
bootJar{
enabled=false
}
/**
* 關(guān)閉父項目的打包功能
*/
jar{
enabled=false
}
14.基礎(chǔ)構(gòu)建完成,為子項目實現(xiàn)簡單的功能.
在eureka-demo下,新建src/main/java以及src/main/resources目錄.
mkdir -p src/main/java
mkdir -p src/main/resources
在src/main/java下構(gòu)建包結(jié)構(gòu).
cd src/main/java && mkdir -p cn/jpanda && cd cn/jpanda
創(chuàng)建啟動類
touch EurekaStart.java && vim EurekaStart.java
然后輸入如下內(nèi)容:
package cn.jpanda;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class, DataSourceAutoConfiguration.class})
public class EurekaStart {
public static void main(String[] args) {
SpringApplication.run(EurekaStart.class, args);
}
}
之后在當(dāng)前項目的根目錄下執(zhí)行
sudo gradle build bootJar
該命令將會將eureka項目打包成可執(zhí)行的jar包.
jar包默認位于:父項目目錄/eureka-demo/build/libs/目錄下.
進入該目錄,可以通過下列命令執(zhí)行該jar文件.
java -jar <jar包>
截至到這,一個簡單的基于gradle搭建的多模塊項目的雛形就出來了.
整合docker.(二選一)
在整合docker的過程中遇到了很多哭笑不得的小問題,待會會記錄一下.
關(guān)于整合docker,在gradle上有很多插件可以實現(xiàn)該功能,這里只針對兩個常用的插件進行整合過程的描述.
使用com.palantir.docker插件.
該插件使用簡單,但是提供的功能相對較少.
在springboot官網(wǎng)上提供了整合該插件的代碼示例,文檔地址
其中不僅整合docker插件,也包含了使用gradle構(gòu)建springboot的示例.
我們就先記錄如何使用該插件.
首先修改父項目的build.gradle文件,在其中引入插件com.palantir.docker
.
在plugin代碼塊中添加代碼:id "com.palantir.docker" version "0.19.2"
.
在configure(allprojects) { project ->...}代碼塊的apply代碼區(qū)域添加代碼apply plugin: 'com.palantir.docker'
之后在文件尾部加入:
configure(subprojects) {
project ->
docker {
dependsOn build
name "${project.group}/${bootJar.baseName}"
files bootJar.archivePath
buildArgs(['JAR_FILE': "${bootJar.archiveName}"])
}
}
并在eureka-demo目錄下新建一個Dockerfile文件,并輸入下面內(nèi)容:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
這樣,在eureka-demo下執(zhí)行命令:
gradle build docker
就會將eureka-demo項目構(gòu)建成一個鏡像.
使用com.bmuschko.docker-java-application和com.bmuschko.docker-remote-api插件
這兩個插件是可以單獨使用的,其功能非常強大,幾乎能夠滿足所有常用的docker操作.
如果已經(jīng)使用了
com.palantir.docker
插件,請先移除相關(guān)的操作結(jié)果(Dockerfile文件不影響后續(xù)操作,可以保留),之后再進行下列操作.
-
step1. 引入
com.bmuschko.docker-java-application
插件
如果只需要構(gòu)建鏡像文件,可以只引入了
com.bmuschko.docker-java-application
插件.
- 在plguins塊中插入下列代碼.
id "com.bmuschko.docker-java-application" version "3.3.6" //通過其遠程API管理Docker鏡像和容器.
id "com.bmuschko.docker-remote-api" version "3.3.6" //Gradle插件,通過其遠程API管理Docker鏡像和容器.
-
step2.應(yīng)用該插件
- 在configure(allprojects) { project ->...}代碼塊的apply代碼區(qū)域,應(yīng)用這兩個插件.
apply plugin: 'com.bmuschko.docker-remote-api'
apply plugin: 'com.bmuschko.docker-java-application'
-
step3.引入插件依賴的文件,并編寫相關(guān)的任務(wù).
- 在文件頂部插入下列代碼:
import com.bmuschko.gradle.docker.tasks.image.*
- 編寫相關(guān)的任務(wù),將下面的代碼放到文件底部.
/**
* ===================================================================================================================
* ------------------------------------------- docker相關(guān)配置 ---------------------------------------------
* ===================================================================================================================
*/
configure(subprojects) {
project ->
// Dockerfile文件存放地址
String dockerFileDir = 'build/docker'
//docker文件
String dockFilePath = "${dockerFileDir}/Dockerfile"
docker {
registryCredentials {
url = 'tcp://192.168.1.179:2375'
}
}
/**
* 創(chuàng)建Dockerfile文件.
*/
task createDockerfile(type: Dockerfile) {
//指定腳本分組
group = "docker"
//腳本依賴 build任務(wù)
dependsOn build
//指定生成的Dockerfile所處的位置.
destFile = project.file(dockFilePath)
//指定依賴的基礎(chǔ)鏡像
from 'openjdk:8-jdk-alpine'
//指定作者信息,但是蓋指令在較新的版本中已經(jīng)被遺棄了,推薦使用label命令.
maintainer 'Jpanda "jpanda@aliyun.com"'
//指定掛載目錄
volume "/tmp"
//擴展標(biāo)簽
label(['author': 'panda', 'email': 'jpanda@aliyun.com'])
//添加參數(shù)
arg "JAR_FILE"
//編譯時將jar包保存進去
copyFile('${JAR_FILE}', "app.jar")
//指定腳本執(zhí)行命令
entryPoint("java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar")
}
/**
* 構(gòu)建基礎(chǔ)鏡像
*/
task image(type: DockerBuildImage) {
group = 'docker'
dependsOn createDockerfile
//指定Dockerfile文件
inputDir = project.file("build/docker")
dockerFile = project.file(dockFilePath)
//標(biāo)簽
tag = "${project.group}/${project.name}:${project.version}"
//指定在執(zhí)行build命令時,使用的構(gòu)建參數(shù).
buildArgs = ["JAR_FILE": "${bootJar.archiveName}"]
/**
* 在構(gòu)建容器前,將jar包和Dockerfile放置到同一目錄下.
*/
doFirst {
copy {
from bootJar
into "${project.buildDir}/docker"
}
}
}
}
配置中涉及到了一塊代碼:
docker {
registryCredentials {
url = 'tcp://192.168.1.179:2375'
}
}
這里的地址可以選擇修改為你的docke注冊地址.
這里面新增了兩個任務(wù),createDockerfile用來生成Dockerfile文件,image用來生成docker鏡像.
其中image任務(wù)依賴了createDockerfile任務(wù),createDockerfile任務(wù)依賴了build任務(wù).
所以我們可以直接在eureka-demo目錄下直接輸入命令:gradle image
來生成鏡像文件.
這時候,看最終構(gòu)建的build.gradle文件內(nèi)容應(yīng)該大致如下(內(nèi)容已經(jīng)被整理過格式):
import com.bmuschko.gradle.docker.tasks.image.*
import org.springframework.boot.gradle.plugin.SpringBootPlugin
/**
*
* ===================================================================================================================
* ===================================================================================================================
* ______ _ _____ __ _ _ _
* | ____| | | / ____| / _(_) | | (_)
* | |__ ___ _ __ _ __ ___ __ _| | | | ___ _ __ | |_ _ __ _ _ _ _ __ __ _| |_ _ ___ _ __
* | __/ _ \| '__| '_ ` _ \ / _` | | | | / _ \| '_ \| _| |/ _` | | | | '__/ _` | __| |/ _ \| '_ \
* | | | (_) | | | | | | | | (_| | | | |___| (_) | | | | | | | (_| | |_| | | | (_| | |_| | (_) | | | |
* |_| \___/|_| |_| |_| |_|\__,_|_| \_____\___/|_| |_|_| |_|\__, |\__,_|_| \__,_|\__|_|\___/|_| |_|
* __/ |
* |___/
* ===================================================================================================================
* ===================================================================================================================
*
* step1.項目構(gòu)建文件,注意,buildscript塊和plugins塊必須作為build.gradle腳本的前兩個塊存在,否則會報錯.
*
*/
/**
* ===================================================================================================================
* ------------------------------------------- 引入項目插件 ----------------------------------------------
* ===================================================================================================================
*/
plugins {
id "com.gradle.build-scan" version "1.8" //生成構(gòu)建分析數(shù)據(jù).
id "net.researchgate.release" version "2.7.0" //用于向使用Gradle的項目提供類似Maven的發(fā)布過程。
id "com.bmuschko.docker-java-application" version "3.3.6" //通過其遠程API管理Docker鏡像和容器.
id "com.bmuschko.docker-remote-api" version "3.3.6" //Gradle插件,通過其遠程API管理Docker鏡像和容器.
id 'org.springframework.boot' version '2.0.1.RELEASE' //spring提供的spring boot插件,主要用到了其依賴管理的功能.
}
/**
* ===================================================================================================================
* ------------------------------------------- 所有項目的通用配置 ----------------------------------------------
* ===================================================================================================================
*/
configure(allprojects) { project ->
//項目基礎(chǔ)屬性
group 'cn.jpanda' //項目所屬組織
version '1.0-SNAPSHOT' //項目版本號
//引入插件
apply plugin: 'java' //java插件
apply plugin: 'maven' //maven插件
apply plugin: 'idea' //IDEA插件
apply plugin: 'eclipse' //eclipse插件
apply plugin: 'org.springframework.boot' //spring boot插件
apply plugin: 'io.spring.dependency-management' //實現(xiàn)maven的依賴統(tǒng)一管理功能
apply plugin: 'com.bmuschko.docker-remote-api'
apply plugin: 'com.bmuschko.docker-java-application'
apply from: "${rootProject.rootDir}/gradle/dependency.gradle" //引入jar包版本配置文件
//JDK版本聲明
sourceCompatibility = custom.version.JDK
targetCompatibility = custom.version.JDK
//配置倉庫
repositories {
mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'https://repo.spring.io/libs-snapshot' }
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
mavenCentral()
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
//指定項目編碼
tasks.withType(JavaCompile) {
options.encoding = "${custom.encoding.OPTIONS}"
}
//在多模塊下,授權(quán)打包依賴模塊
jar {
enabled = true
}
//重打包基礎(chǔ)配置
bootJar {
// mainClassName = "jpanda.cloud.EurekaServer"
launchScript()
archiveName = "${project.group}_${project.name}_${project.version}.jar"
}
}
/**
* ===================================================================================================================
* ------------------------------------------- 所有子項目的通用配置 ---------------------------------------------
* ===================================================================================================================
*/
configure(subprojects) {
project ->
dependencyManagement {
overriddenByDependencies = false
dependencies {
imports {
/**
* 通過依賴spring boot dependencies來取代繼承spring-boot-starter-parent,
* 該配置可以省略.
*/
mavenBom SpringBootPlugin.BOM_COORDINATES
/**
* 通過依賴spring cloud dependencies 來統(tǒng)一管理spring cloud 的版本
*/
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${custom.version.SPRING_CLOUD}"
}
/**
* mybatis-spring-boot整合包,該項目必須采用dependency來管理版本,而不能使用mavenBom,
* 使用mavenBom可能會導(dǎo)致其依賴的jar包和spring依賴的版本發(fā)生沖突.
*/
dependency "org.mybatis.spring.boot:mybatis-spring-boot-starter:${custom.version.SPRING_BOOT_MYBATIS}"
/**
* 阿里巴巴druid數(shù)據(jù)庫連接池
*/
dependency "com.alibaba:druid:${custom.version.ALI_DRUID}"
/**
* fastJson https://mvnrepository.com/artifact/com.alibaba/fastjson
*/
dependency "com.alibaba:fastjson:${custom.version.ALI_FASTJSON}"
/**
* druid數(shù)據(jù)庫連接池和spring-boot整合包
*/
dependency "com.alibaba:druid-spring-boot-starter:${custom.version.SPRING_BOOT_DRUID}"
/**
* 分頁插件
*/
dependency "com.github.pagehelper:pagehelper-spring-boot-starter:${custom.version.PAGEHELPER}"
/**
* 對象實體轉(zhuǎn)換工具包
*/
dependency "com.github.jmnarloch:modelmapper-spring-boot-starter:${custom.version.SPRING_BOOT_MODELMAPPER}"
/**
* Apache Commons IO庫包含實用程序類,流實現(xiàn),文件過濾器,文件比較器,endian轉(zhuǎn)換類等等.
*/
dependency "commons-io:commons-io:${custom.version.APACHE_COMMON_IO}"
}
}
}
configure(subprojects) {
project ->
/**
* -============================================================================================================
* -=====================================此處存放業(yè)務(wù)模塊的公共依賴==================================================
* -============================================================================================================
*/
dependencies {
/**
* -=================================================================================-
* - ******************** [運維]性質(zhì)相關(guān)依賴 *************************** -
* -=================================================================================-
*/
//服務(wù)監(jiān)控中心
compile 'org.springframework.boot:spring-boot-actuator'
//eureka注冊客戶端
compile 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
//全局統(tǒng)一配置中心
compile 'org.springframework.cloud:spring-cloud-starter-config'
//ribbon負載均衡依賴
compile 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon'
//spring cloud openfeign依賴,原feign已經(jīng)棄用,簡化調(diào)用方式
compile 'org.springframework.cloud:spring-cloud-starter-openfeign'
//spring cloud hystrix 保護模塊
compile 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'
/**
* -=================================================================================-
* - ******************** [工具/功能]性質(zhì)相關(guān)依賴 *************************** -
* -=================================================================================-
*/
//Json處理工具
compile 'com.alibaba:fastjson'
// Apache Commons IO庫包含實用程序類,流實現(xiàn),文件過濾器,文件比較器,endian轉(zhuǎn)換類等等.
compile 'commons-io:commons-io'
//使用lombok來簡化掉編碼過程中的通用的方法.
compile 'org.projectlombok:lombok'
//對象映射工具modelMapper
compile 'com.github.jmnarloch:modelmapper-spring-boot-starter'
//spring boot安全依賴
compile 'org.springframework.boot:spring-boot-starter-security'
//自定義配置管理
compile 'org.springframework.boot:spring-boot-configuration-processor'
/**
* -=================================================================================-
* - ******************** [數(shù)據(jù)庫]性質(zhì)相關(guān)依賴 *************************** -
* -=================================================================================-
*/
//阿里巴巴druid數(shù)據(jù)庫連接池
compile 'com.alibaba:druid'
//jdbc相關(guān)配置
runtime 'mysql:mysql-connector-java'
// druid數(shù)據(jù)庫連接池和spring-boot整合包
compile 'com.alibaba:druid-spring-boot-starter'
//mybatis-spring-boot整合包
compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter'
//分頁插件
compile 'com.github.pagehelper:pagehelper-spring-boot-starter'
//測試依賴
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
}
/**
* ===================================================================================================================
* ------------------------------------------- docker相關(guān)配置 ---------------------------------------------
* ===================================================================================================================
*/
configure(subprojects) {
project ->
// Dockerfile文件存放地址
String dockerFileDir = 'build/docker'
//docker文件
String dockFilePath = "${dockerFileDir}/Dockerfile"
docker {
registryCredentials {
url = 'tcp://192.168.1.179:2375'
}
}
/**
* 創(chuàng)建Dockerfile文件.
*/
task createDockerfile(type: Dockerfile) {
//指定腳本分組
group = "docker"
//腳本依賴 build任務(wù)
dependsOn build
//指定生成的Dockerfile所處的位置.
destFile = project.file(dockFilePath)
//指定依賴的基礎(chǔ)鏡像
from 'openjdk:8-jdk-alpine'
//指定作者信息,但是蓋指令在較新的版本中已經(jīng)被遺棄了,推薦使用label命令.
maintainer 'Jpanda "jpanda@aliyun.com"'
//指定掛載目錄
volume "/tmp"
//擴展標(biāo)簽
label(['author': 'panda', 'email': 'jpanda@aliyun.com'])
//添加參數(shù)
arg "JAR_FILE"
//編譯時將jar包保存進去
copyFile('${JAR_FILE}', "app.jar")
//指定腳本執(zhí)行命令
entryPoint("java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar")
}
/**
* 構(gòu)建基礎(chǔ)鏡像
*/
task image(type: DockerBuildImage) {
group = 'docker'
dependsOn createDockerfile
//指定Dockerfile文件
inputDir = project.file("build/docker")
dockerFile = project.file(dockFilePath)
//標(biāo)簽
tag = "${project.group}/${project.name}:${project.version}"
//指定在執(zhí)行build命令時,使用的構(gòu)建參數(shù).
buildArgs = ["JAR_FILE": "${bootJar.archiveName}"]
/**
* 在構(gòu)建容器前,將jar包和Dockerfile放置到同一目錄下.
*/
doFirst {
copy {
from bootJar
into "${project.buildDir}/docker"
}
}
}
}
/**
* ===================================================================================================================
* ------------------------------------------- 基礎(chǔ)配置 ---------------------------------------------
* ===================================================================================================================
*/
/**
* 生成gradlew文件,統(tǒng)一gradle版本,避免因為版本不同產(chǎn)生的問題
*/
task wrapper(type: Wrapper) {
gradleVersion = "4.8"
}
/**
* 生成構(gòu)建分析報告.
*/
buildScan {
licenseAgreementUrl = 'https://gradle.com/terms-of-service'
//授權(quán)
licenseAgree = 'yes'
}
/**
* 關(guān)閉父項目的打包功能
*/
bootJar{
enabled=false
}
/**
* 關(guān)閉父項目的打包功能
*/
jar{
enabled=false
}
其他
項目構(gòu)建過程中,需要注意執(zhí)行命令時的用戶權(quán)限,有些時候可能加上sudo就能解決一些報錯.
生成jar包的名稱需要注意不要包含特殊符號,包括構(gòu)建鏡像時的jar包.
如果封裝了gradle wrapper,不妨使用./gradlew 來代替文中的gradle命令.
腳本對應(yīng)的項目已經(jīng)放到了gitee上,點擊查看.