使用 Gradle 構建 Docker 映象

Mondo 科技 更新 2024-02-03

基於 Gradle,無需安裝 Docker Toolbox,即可生成 Docker 映象。

Docker是乙個開源的基於LXC的輕量級容器管理器,在Docker的幫助下,開發者只需要將應用和依賴的執行環境打包成乙個可移植的容器,就可以正常執行,不受語言、框架和底層作業系統的限制,使用Docker可以縮短開發時間、探索時間和部署週期, 這樣他們就可以更高效地編碼,簡化開發環境,消除依賴衝突等,並最終提高開發生產力。

但是,當 Windows 平台使用 Docker 技術時,需要安裝和配置額外的 Docker 工具,這不可避免地會花費額外的工作時間,如果想在 Dev 環境中配置一組與生產環境一致的構建環境,則需要花費大量的精力。

為了加快開發構建速度,顯著提高開發場景中的開發效率,建議使用 Gradle 進行構建,並使用 Gradle 指令碼高效便捷地管理專案中的差異、依賴、編譯、打包和部署過程。 本文將重點介紹 Gradle 的使用以及如何使用 Gradle 建立 Docker 映象,如何利用 Gradle 指令碼以及如何從開發人員的角度使用中央 Docker 引擎構建 Docker 映象。

在傳統的構建系統中,會使用 ant 和 m**en 作為構建工具,這裡推薦的是 gradle,它不使用 xml 作為配置檔案,而是使用基於 groovy 開發的 DSL,因此 gradle 的配置檔案比 ant 和 m**en 的配置檔案更高效、更簡潔。 以下是 Gradle 和 Ant 以及 M**En 之間的主要區別

ANT是最早的構建工具,它的核心是用J**A編寫的,使用XML作為構建指令碼,因為它基於J**A,允許在任何環境中執行構建。 ANT基於任務鏈的思想,它定義了任務之間的依賴關係並形成乙個序列。 缺點是使用 XML 定義構建指令碼會導致指令碼臃腫,而 ANT 本身不提供專案構建的指導,導致構建指令碼不同,開發人員需要熟悉每個專案的指令碼內容,並且不提供 ANT 生態系統中的依賴管理工具。 M**en 意識到 ANTU 的不足,採用標準的專案布局、統一的生命週期和強大的依賴管理,使用“約定勝於配置”的思想,減少構建指令碼的配置,提高開發效率和管理秩序,擁有活躍的社群,可以通過合適的外掛程式輕鬆擴充套件。 缺點是它有乙個預設的結構和生命週期,有很多限制,編寫外掛程式擴充套件很麻煩,並且使用xml作為構建指令碼,使構建指令碼冗長。 Gradle 兼具 ANT 和 M**EN 的優勢,具有 ANT 的強大和靈活性,並繼承了 M**EN 的生命週期管理。 它使用基於 Groovy 的 DSL,並提供宣告式構建語言,簡單明瞭,使 Gradle 構建指令碼更加簡潔明瞭,並使用具有完全可配置性的標準專案布局。 您還可以擴充套件外掛程式以提供預設的構建生命週期、自定義任務、單獨執行任務以及定義任務之間的依賴關係。 Gradle 繼承並改進了 m**en 的依賴管理,可以與 m**en 和 ivy 倉庫結合使用; 同時,它與 ant 本身相容,並有效地復用 ant 的任務; 外掛程式實現方式多樣,有很強的官方外掛程式庫; 從構建級別來看,它支援從 ant 和 m**en 的逐步遷移; 通過包裝器實現跨平台的無縫相容性。 JDK:最新的 J**A8 版本,安裝和配置環境變數。 gradle 構建工具:請轉到最新的完整版本。 Eclipse:Eclipse IDE for j**a EE Developers 版本,請轉到 *** 最新版本。 Gradle 的核心是 Groovy,而 Groovy 的本質是 J**A,所以很明顯 Gradle 環境必須依賴 JDK 和 Groovy 庫,所以需要先安裝 JDK 並配置環境變數。

* gradle-4.5-all,從 Gralde 中選擇最新版本,然後解壓到指定目錄,將 gradle 的 bin 目錄新增到 path 變數中,配置環境變數。 檢查是否配置了gradle環境變數。 在 cmd 命令列中輸入 gradle -v,如果出現類似如下訊息的訊息,則表示 gradle 環境配置成功。

---gradle 4.5---build time: 2018-01-24 17:04:52 utcrevision: 77d0ec90636f43669dc794ca17ef80dd65457becgroovy: 2.4.12ant: apache ant(tm) version 1.9.9 compiled on february 2 2017jvm: 1.8.0_151 (ibm corporation 2.9)os: windows 7 6.1 amd64
注意:以上資訊可能因 Gradle 版本或不同環境而異。

新建乙個名為 gradle project 的根目錄,以多個子專案為例,所以還需要在 gradle 專案目錄下建立乙個子目錄

gradle_project_util;gradle_project_model;gradle_project_web;
建立內部版本gradle 檔案,其中包含以下內容:

清單 1根專案 gradle 配置。

subprojects jcenter } dependencies {}version = '1.0' jar }
建立設定Gradle 檔案, 設定gradle 檔案用於管理整個專案,宣告當前專案中有哪些模組等。 具體如下:

清單 2根專案設定配置。

rootproject.name = "gradle_project"include "gradle_project_util","gradle_project_model","gradle_project_web"
建立完成後,顯示如下圖:

圖1目錄結構的示例。

在子專案中建立生成gradle 檔案並新增如下內容: 清單 3子專案 gradle 指令碼。

apply plugin: 'j**a' repositories dependencies /***project template***/ task createdirs sourcesets*.resources.srcdirs*.each }
在 cmd 命令列上執行 :gradle createdirs 命令列,命令執行後會建立 j**a 專案的標準目錄結構。

Gradle 遵循 COC(約定重於配置)理念,預設提供與 M**en 相同的專案結構配置。 一般結構如下:

sub-project root

src main j**a (專案目錄)src main resources (project resource directory)src test j**a (test source directory)src test resources (test resource directory) 將 Gradle 專案匯入 Eclipse: 在 Eclipse 選單中選擇 file->import->gradle,如下圖所示:

圖2專案匯入示例。

選擇下一步後,選擇 gradle 專案所在的目錄,然後繼續選擇預設值繼續下一步,直到專案結構解析完成,如下圖所示:

圖3Gradle 專案結構示例。

匯入完成後,下圖顯示了 Eclipse 中 Project Explore 中顯示的專案結構,並建立了與 M**en 一致的專案結構。

圖4專案探索示例。

基於 gradle 的指令碼的本質是 groovy 指令碼,當執行一種型別的配置指令碼時,會建立乙個關聯物件,例如,在執行構建指令碼指令碼時會建立乙個專案物件,這個物件實際上是乙個 gradle 物件。

下面介紹了 Gradle 的三個主要物件:

gradle object:這是構建初始化時建立的唯一物件,一般不建議修改此預設配置。 設定物件:每個設定gradle(gradle 的設定檔案,其約定名稱由 settings 定義。gradle) 將轉換為設定物件,該物件在初始化階段執行,對於多專案構建,您必須確保有設定gradle 檔案,對於單專案構建設定檔案是可選的,但建議您仍然需要配置它。 專案物件:每個生成Gradle 將轉換為 Project 物件。 Gradle 的三種不同紀元指令碼分別用於以下用途:

初始化指令碼 init script(gradle)。

Gradle 物件:初始化指令碼 Init 指令碼 (Gradle) 與其他型別的 Gradle 指令碼類似,因為它們在構建開始之前執行,主要用於為下乙個構建指令碼做準備。 如果我們需要編寫乙個初始化指令碼,init 指令碼,我們可以按照規則將其放置在使用者家中gradle。

初始化指令碼的 gradle 物件表示 gradle 的排程,我們可以通過呼叫專案物件的 getgradle() 方法獲取 gradle 例項物件。

設定指令碼設定指令碼(settings)。

Settings 物件:設定例項和設定gradle 檔案是一對一的對應關係,用於配置一些專案設定。 此檔案通常放在專案的根目錄中。

構建指令碼(專案)。

在 Gradle 中,每個要編譯的專案都是乙個專案(每個專案的構建gradle 對應乙個專案物件),每個專案都是用一系列任務構建的,其中許多任務預設由 gradle 外掛程式支援。當我們編寫 gradle 指令碼時,我們大部分時間都是在編寫構建指令碼,因此專案和指令碼物件的屬性和方法等 API 非常重要。

每個專案物件和生成Gradle 是一對一的對應關係,乙個專案在構建時有如程:

為當前專案建立型別設定的例項。 如果當前專案中有設定gradle 檔案,請使用此檔案來配置您剛剛建立的 settings 例項。 通過設定例項的配置,在專案層次結構中建立專案物件的例項。 最後,上面建立的專案物件例項執行生成。 對於每個專案gradle 指令碼。 作為構建指令碼的開發者,你不應該只侷限於編寫任務動作或配置邏輯,有時候你想在指定的生命週期事件發生時執行乙個**,這裡你需要了解生命週期事件。 生命週期事件可以發生在指定的生命週期之前、期間或之後,在執行階段之後發生的生命週期事件被視為完成。 具體實施週期如下圖所示

圖5Gradle 生命週期圖。

初始化階段:Gradle 支援單專案和多專案構建,在初始化階段,gradle 決定哪些專案需要新增到構建中,並為這些需要新增到構建中的專案建立專案例項,本質上是執行設定gradple 指令碼。

配置階段:配置階段決定了整個構建的專案和任務之間的關係,它會建立乙個有向圖來描述任務之間的相互依賴關係,並解析構建。 新增到構建專案的每個生成gradle 指令碼。

執行階段:執行階段是生成 gradle 來執行根專案和每個子專案下的自定義任務及其所依賴的任務,以實現最終的構建目標。

正如你所看到的,生命週期實際上可以與上面構建指令碼的執行過程相關。

在多專案構造中,需要指定乙個樹根,樹中的每個節點代表乙個專案,每個專案物件都指定了乙個表示樹中位置的路徑。 一般做法是確保有設定gradle 檔案是在最初建立 gradle 專案時定義的,因此稍後將在構建指令碼檔案中對其進行擴充套件。

如前所述,gradle 構建指令碼由一系列任務組成,首先要了解如何編寫任務

清單 4有操作任務指令碼,也沒有操作任務指令碼。

TaskTask 你好 }沒有 Action 的任務,這是乙個快捷方式,替換 Dolast,稍後解釋 Task Hello <<
在上面的例子中,如果任務沒有用“”執行,則任務在指令碼的初始化階段執行(即執行任何任務),如果執行,則會在gradle actiontask之後執行。 因為如果不新增 “”,則會在任務函式返回之前執行閉包,如果新增 “”,則會呼叫 actiontaskdolast(),所以會等到gradle actiontask執行完畢,這一點必須記住,因為在具體的使用過程中,你會發現同乙個任務可能沒有按照任務依賴的順序執行,你應該考慮是否受到這種寫入的影響。

通過上面這個任務的基本感覺的例子,可以發現乙個構建gradle 檔案定義了多個彼此無關的任務,並確定了 gradle 命令後跟的任務名稱。 如果我們希望它們之間有依賴關係,先做什麼,以後做什麼怎麼辦? 讓我們看一下以下內容:

清單 5任務取決於指令碼。

task taskx(dependson: 'tasky')$ gradle taskx> task :taskytasky> task :taskxtaskxbuild successful in 0s2 actionable tasks: 2 executed
這是如何使用 dependson 將兩個單獨的任務相互連線。

您還可以在 Gradle 中使用 Groovy 建立動態任務,如下所示:

清單 6建立動態任務指令碼。

4.times }
結果如下:

$ gradle task1> task :task1i'm task number 1build successful in 0s1 actionable task: 1 executed
除了在定義上述任務時指定依賴關係外,還可以通過 API 為任務新增依賴關係,如下所示:

清單 7task 表示依賴指令碼。

4.times }task0.dependson task1, task1
結果如下:

$ gradle task0> task :task1i'm task number 1> task :task2i'm task number 2> task :task0i'm task number 0build successful in 0s3 actionable tasks: 3 executed
您還可以通過 API 向任務新增一些新行為,例如:

清單 8任務 dofirst,dolast 指令碼。

task hello <$gradle hello> task :hellohello venushello earthhello marshello jupiterbuild successful in 0s1 actionable task: 1 executed
正如你所看到的,dofirst 和 dolast 可以多次執行,“運算子本質上是 dolast。

您還可以使用美元符號作為其他任務的屬性,如下所示:

清單 9任務引用指令碼。

task hello <$gradle hello> task :hellohello world!greetings from the hello task.build successful in 0s1 actionable task: 1 executed
上面指令碼中使用的名稱實際上是任務的預設屬性,它表示當前任務的名稱。

您還可以向任務新增自定義屬性,如以下示例所示:

清單 10任務自定義屬性指令碼。

task task1 task printtaskproperties <<
結果如下:

$ gradle printtaskproperties> task :printtaskpropertiesvaluebuild successful in 0s1 actionable task: 1 executed
此外,gradle 允許您在指令碼中定義乙個或多個預設任務,如下所示:

清單 11任務自定義任務指令碼。

defaulttasks 'clean', 'run'task clean <$gradle> task :cleandefault cleaning!> task :rundefault running!build successful in 0s2 actionable tasks: 2 executed
如前所述,gradle 在構建指令碼中定義了乙個專案,對於構建指令碼中的每個子專案,gradle 都會建立乙個要關聯的專案物件,在執行構建指令碼時,它會配置關聯的專案物件; 生成指令碼中呼叫的每個方法和屬性都委託給當前 Project 物件。

專案物件提供了一些標準屬性,這些屬性便於在生成指令碼中使用。

有關特定於專案的方法的詳細資訊,請參閱專案的文件。 對於 J**A 專案,一般需要在構建開始前清理之前的構建結果,啟動構建,將構建結果複製到指定目錄,將其他需要的配置、指令碼等複製到指定目錄,以上步驟都是構建 Docker 映象的準備步驟。 具體如下:

清單 12Gradle 構建指令碼。

apply plugin: 'j**a' repositories dependencies task cleandocker(type: delete) /docker") task copybuild(type: copy, dependson: build) -jar" into 'build/docker' } task copyscript(type: copy, dependson: copybuild) /resources/main/script") into project.file("$/docker/script")}
執行完成後,結果如下:

$ gradle copyscriptbuild successful in 1s5 actionable tasks: 5 executed
同時,可以發現在構建$projectdir的專案構建目錄下有構建生成的檔案、複製的配置檔案和指令碼檔案,如下圖所示

圖6構建結果圖。

在 J**A 專案中,一些常用的 ** 是同時被多個專案引用的,對於這部分程式碼需要在常用專案中提及,並編譯成乙個 jar 包並發布到倉庫中,這樣需要使用 common ** 的專案只需要根據 jar 包資訊下載倉庫中最新版本的 jar 包即可。

通常,您可以按如下方式新增專案依賴項:

dependencies
在 gradle 中,依賴可以組合成配置,配置就是一系列依賴,通常理解為依賴配置,可以用來宣告專案的外部依賴,也可以用來宣告專案的發布。 下面我們給出一些 j**a 外掛程式中的常見配置,如下所示:

compile:用於編譯對專案原始碼的依賴; runtime:執行時生成的類所需的依賴項,預設項,包括編譯時的依賴項; testcompile:編譯測試依賴,預設項,包含執行生成的類所需的依賴和編譯源的依賴;testRuntime:執行測試所需的依賴,預設項,包括以上三個依賴; Gradle 可以宣告許多依賴項,其中乙個是外部依賴項,即當前構建之外的依賴項,通常儲存在遠端(例如 m**en)或本地儲存庫中。 下面是外部依賴項的示例:

dependencies
如您所見,引用外部依賴項需要 group、name 和 version 屬性。 以上是兩種不同的外部依賴書寫方式,其中第二種是速記。

根據 j**a 發布 jar 包的規範,一般發布 jar 包還需要附帶乙個源**,供使用者參考和使用。 因此,當它被打包成乙個 jar 時,原始碼也會被打包,如下**:

清單 13jar 打包指令碼。

task sourcejar(type: jar)
此外,您還需要配置上傳 jar 包和倉庫資訊

清單 14jar 發布指令碼。

publishing }artifactory defaults }}
這裡的配置是:遠端倉庫的URL位址、使用者名稱、密碼等資訊,根據上面的gradle指令碼,將發布通用專案的**,供其他專案使用。

與過去使用 war 包發布 J**A 應用類似,現在的微服務和 Web 應用大多是使用 docker 映象發布的,本文開頭已經介紹了 docker 映象發布的便利性,這裡就不深入展開了。

在本節中,我們將介紹如何確保每個開發人員發布用於測試的 Docker 映象與生產環境中發布的映象一致。 這裡介紹中央 Docker 引擎的概念,是為了保證每個開發者都通過中央引擎構建乙個 Docker 映象,而不需要每個開發者在開發環境中配置 Docker Engine,從而消除因 Docker Toolbox 版本不同、作業系統不同而導致的 Docker Build 環境差異。 中央 Docker 引擎的概念如下圖所示:

圖7中央 Docker 引擎示例圖。

集中式構建需要中央 Docker 引擎,配置資訊基於 CentOS 73.其他作業系統也可以基於上述概念進行配置。 配置的主要思想是在 Linux Server 上安裝 Docker Engine,在 Docker Engine 中配置 2375 TCP 埠,並在防火牆中釋放此埠,以便其他服務可以連線遠端構建。 具體步驟如下:

使用以下命令安裝 docker 和 docker 引擎:

sudo yum install docker-io

sudo yum install docker-engine

安裝上述命令後,還需要配置 docker。

修改 lib systemd 系統 docker服務中的以下兩行是:

environmentfile=-/etc/sysconfig/docker

execstart=/usr/bin/dockerd $docker_opts

將 etc sysconfig docker 的內容修改為以下值:

docker_opts=’-h tcp: -h unix:///var/run/docker.sock’
防火牆釋放埠 2375。

firewall-cmd –zone=public –add-port=2375/tcp –permanent

firewall-cmd –reload

完成上述配置後,中央 Docker 引擎就已設定完畢。

由於主要使用plugin:combmuschko.docker-remote-api 完成對遠端 docker 引擎的呼叫,這裡將介紹 gradle 外掛程式。

其實gradle的核心主要是乙個框架,所謂gradle就是簡單快捷的構建,其實它是由一系列外掛程式支援的,外掛程式增加了新的任務。 Gradle 中一般有兩種型別的外掛程式,如下所示:

指令碼外掛程式是額外的構建指令碼,用於進一步配置構建,通常在構建內部使用。 指令碼外掛程式可以從本地檔案系統獲取,也可以遠端獲取,如果從檔案系統獲取,則相對於專案目錄,如果遠端獲取,則由 http url 指定。

二進位外掛程式是實現外掛程式介面的類,並以程式設計方式為構建提供一些有用的任務。

引用外掛程式需要通過專案完成apply() 方法完成宣告申請,同乙個外掛程式可以多次應用。 下面是乙個示例:

指令碼外掛程式應用自:'build.gradle'二進位外掛程式應用外掛程式:'j**a'
外掛程式還可以使用外掛程式 ID,這些 ID 用作給定外掛程式的唯一識別符號,並且可以使用縮寫字元 ID 進行註冊以供以後使用。 例如,下面是乙個示例:

由 j**a 外掛程式的 id 引用。 

apply plugin: codecheck

在上一節中,我們談到了如何使用 Gradle 外掛程式,在本節中,我們將使用 Gradle 外掛程式來構建乙個依賴於 plugin:com 的 Docker 映象bmuschko.docker-remote-api 完成 Docker 映象的遠端構建和發布。

在構建 Docker 映象之前,需要使用 gradle 指令碼完成一系列的準備工作,包括將配置檔案和啟動指令碼複製到指定目錄,構建目標 jar 包,然後使用 gradle 外掛程式生成 dockerfile,然後根據 dockerfile 資訊進行發布。

配置 Docker 引擎資訊。

清單 15Docker 引擎資訊配置指令碼。

docker else registrycredentials }
上面的指令碼會根據是 Windows 平台還是 Linux 平台使用不同的 URL,直接使用 DockerSock、Windows 平台需要通過 TCP 埠連線到 Docker Engine。

準備工作,包括清除以前構建的舊版本以及將編譯結果複製到目標目錄。

清單 16docker 預準備指令碼。

task cleandocker(type: delete) /docker") }task copybuild(type: copy, dependson: build) -jar" into 'build/docker'}task copyscript(type: copy, dependson: copybuild) /resources/main/script") into project.file("$/docker/script")}
生成 dockerfile

清單 17生成 dockerfile 指令碼。

task createdockerfile(type: dockerfile, dependson: copyscript) -jar", docker_work_home addfile 'script', "$/script" environmentvariable 'j**a_opts' , j**a_opts environmentvariable 'boot_target' , "$-$jar" runcommand "chmod +x /home/root/script/*.sh" entrypoint("sh", "-c", /home/root /script/startup.sh")}
構建 Docker 映象、標記、發布

清單 18發布 docker 映象指令碼。

task builddockerimage(type: dockerbuildimage, dependson: createdockerfile) task builddockertagimage(type: dockertagimage, dependson: builddockerimage) repository = docker_image conventionmapping.tag = force = true}task pushimage(type: dockerpushimage, dependson: builddockertagimage) conventionmapping.tag = } artifactorypublish
最後,在 cmd 中執行命令:gradle artifactorypublish 以完成 docker 映象構建和發布。

對於團隊協作環境,與其為每個開發者單獨構建乙個Docker環境,不如構建一套與生產環境一致的Central Docker Engine環境,這樣既方便維護,又保證了開發者生成的Docker映象與生產環境生成的Docker映象一致。 以上只是實際專案中的一點個人想法,如果有不足之處,希望讀者能夠海瀚,如果有,希望讀者能夠反饋,交流經驗,共同進步。

相關問題答案

    運用智慧型化技術構建醫院後勤服務資訊管理系統

    物質醫院的智慧型化建設一直走在行業前列,尤其是當涉及到醫院業務相關的系統時,智慧型化程度比其他系統更強大,作為醫院物流鏈部門,智慧型化改造的需求正在逐漸增加。目前,醫院後勤管理部門作為醫院運營的重要支撐系統,在管理層面面臨諸多挑戰。首先,醫院物流鏈部門面臨著越來越大的成本壓力。隨著醫療技術的飛速發展...

    使用小程式為教育機構構建高效的管理系統

    隨著網際網絡的飛速發展,線上教育也越來越受到關注和普及。為了滿足學生和家長的需求,教育機構開發了自己的小程式管理系統。本文將詳細介紹如何使用巧拓雲平台一鍵開發自己的教育機構小程式管理系統。.進入喬拓雲的背景。首先,在瀏覽器中搜尋喬拓雲,登入後台,選擇教育系統,點選進入。在這裡,您可以看到各種教育小程...

    職工活動中心如何利用氣穹結構建築打造室內運動場館?

    在職工活動中心的建設中,如何打造乙個舒適實用的室內體育場館,一直是大家關注的焦點。近年來,作為一種新型的建築形式,空氣膜結構建築逐漸出現在體育場館的建設中。今天,我們就來看看如何利用氣穹結構建築在職工活動中心建造室內體育場,以及其背後的優勢和要點。 空氣膜結構建築在職工活動中心室內體育場的應用優勢。...

    利用智慧型電表實現舊舊再利用,構建迴圈生態圈,實現數位化能源管理

    近年來,我國智慧型電網產業政策密集出台,國家扶持力度不斷加大。隨著數字智慧型電網的加速發展,智慧型電表市場和利潤空間正在迅速擴大 根據中國研究院普華研究所的筆文 年中國智慧型電表市場深度研究報告 顯示 國家電網智慧型電表覆蓋率達 累計收款億戶,新增智慧型電表臺,個 電表回收生態系統 隨著智慧型電網建...

    AI Analytics 構建面向未來的分析智慧型

    近日,由恒石科技 亞馬遜雲科技 一線數智聯合主辦的以 探索SaaS新增長,AI 分析賦能SaaS新價值 為主題的企業數位化成長研討會第二場在上海成功舉辦。數十家SaaS企業服務企業CEO CIO等高管齊聚一堂,共同探討AI新技術如何為SaaS賦能 創造新價值,以及如何通過生態合作降本增效。恆石科技深...