JavaRush /Java Blog /Random-TW /我們實作應用程式部署-《Java專案從A到Z》
Roman Beekeeper
等級 35

我們實作應用程式部署-《Java專案從A到Z》

在 Random-TW 群組發布
大家好。我們將繼續撰寫有關編寫專案的系列文章。 「Java 專案從頭到尾」:實作應用程式部署 - 1

對分支進行排序

重要的是,為了不迷失分支及其在儲存庫中的順序,我決定透過添加STEP_{number}前綴來重新命名它們。例如,除了主分支之外,我們還有三個分支:
  • JRTB-0
  • JRTB-2
  • JRTB-3
你不會立即明白應該先哪一個。所以我將它們重命名如下:
  • STEP_1_JRTB-0 - 第一步
  • STEP_2_JRTB-2 - 第二步
  • STEP_3_JRTB-3 - 第三步
下一篇文章以此類推。要重命名分支,請轉到存儲庫頁面,找到分支框,然後按照它操作:「Java 專案從頭到尾」:實作應用程式部署 - 2在每個分支下,單擊鉛筆並重命名分支:「Java 專案從頭到尾」:實作應用程式部署 - 3結果我們得到:「Java 專案從頭到尾」:實作應用程式部署 - 4順便說一句,訂閱我的電報頻道的每個人都發現我立即重命名了分支機構。

關於 Docker 的一些知識

什麼是 Docker?簡而言之,它是一個工具,您可以使用它快速、安全地部署(部署)應用程序,為它們創建一個僅對它們必要的封閉基礎設施。還是很難,我懂。總的來說,Docker可以理解為一個可以快速且有效率地工作的開發平台。Docker可以理解為運行在伺服器上的程式。該程式能夠儲存帶有應用程式的容器。什麼是容器?這是一個獨立的基礎設施,您可以在其中添加所需的一切。例如,對於Java應用程序,我們需要一個JRE來運行應用程序,容器將有這個,我們將需要一些其他軟體 - 我們可以添加這個。或者我們需要 Linux 和 Tomcat servlet 容器。這也是可以做到的。容器是基於映像創建的:也就是說,這是一個特定的模板,其中包含創建 Docker 容器所需的所有內容。如何創建這個圖像?在我們的範例中,我們需要在專案的根目錄中建立一個 Dockerfile 來描述容器中應該包含的內容。由於我們不想在任何地方公開機器人的令牌,因此每次要部署應用程式時都必須傳遞它。您可以在此處此處閱讀有關此主題的更多資訊。

我們寫JRTB-13

我們需要為我們的應用程式設定一個快速且簡單的部署過程到伺服器。也就是說,對於一台 24/7 工作的機器。讓我們以 Docker 為基礎。但我們的清單中沒有任務負責新增此功能。不知何故,我在創建它時錯過了它。沒問題,我們現在就創建它。前往GitHub 上的問題建立選項卡,然後選擇功能請求:「Java 專案從頭到尾」:實作應用程式部署 - 5新增任務描述、接受標準,設定此問題屬於哪個項目,然後您可以建立新問題:「Java 專案從頭到尾」:實作應用程式部署 - 6現在,顯示任務已被接受對於工作,將任務的狀態從「進行中」改為「待辦事項」:「Java 專案從頭到尾」:實作應用程式部署 - 7這將是一篇困難的文章。如果有任何問題,請在評論中寫下:我會盡力監控並回答。這將是一個小型的客戶支援:D

建立 Dockerfile

什麼是 dockerfile?對於 Docker,這是一個關於如何為 Docker 容器建立映像的腳本(逐步說明)。為了讓我們的應用程式正常運作,我們需要 JDK 版本 11。也就是說,我們需要找到 JDK 11 docker 映像並將其新增到我們的映像中。這類似於我們向記憶體添加依賴項的方式。Docker為此提供了DockerHub。要在本地下載圖像,您需要在那裡註冊。註冊完成後,我們去找JDK11。根據我的發現,這是容器:adoptopenjdk/openjdk11。該容器的描述包含 dockerfile 所需的內容:
FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
讓我們修復從中獲取 jar 檔案的資料夾。運行 mvn package maven 任務後,我們將其放在目標資料夾中。在完成這一切之前,基於更新的主分支,我們為我們的任務建立一個新分支:STEP_4_JRTB-13。現在你可以工作了。在專案的根目錄中,建立一個不帶Dockerfile副檔名的文件,並在其中加入以下內容:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
第一行是鏡像所依據的內容 - 採用openjdk/openjdk11。第二行是為名為 JAR_FILE 的映像新增一個參數,該映像位於目標資料夾中。此外,目前資料夾是由 Dockerfile 的位置決定的。第三行 - 將我們專案的 jar 複製到 docker 映像中。最後一行本質上包含一個根據終端機中的命令建立的數組,該數組以空格分隔。也就是說,最終將執行以下命令:「java -jar /app.jar」 為了使機器人令牌保密,在啟動容器時,我們需要傳遞兩個變數 - 機器人的名稱及其令牌。為此,我們將編寫一個查詢,該查詢應該使用變數啟動我們的專案。以及如何做呢?你需要谷歌它:這是第一個帶有正常描述的連結。我們想做什麼?我們在 application.properties 檔案中定義了兩個變數:
  • 機器人用戶名
  • 機器人令牌
我想運行一個 docker 容器並每次都將我的值傳遞到那裡,這樣就沒有人可以看到這些值。我知道在SpringBoot中,jar專案啟動時設定的環境變數將優先於application.properties檔案中的環境變數。要在請求中傳遞變量,您需要添加以下結構:-D{變量名稱}=”{變量值}”。我們不添加大括號;)我們將收到一個請求,該請求將使用預定義值啟動我們的應用程式 - 機器人的名稱和令牌: java -jar -Dbot.username=”test.javarush.community_bot” - Dbot. token=”dfgkdjfglkdjfglkdjfgk” *.jar 現在我們需要在 docker 容器內傳遞這些變數。這是一個環境變數。為了確保將來我們的資料庫順利運行並且我們的應用程式不會出現問題,我們將使用 docker-compose。這是一個單獨的工具,您可以在其中組織工作、啟動和容器之間的依賴關係。換句話說,它是 Docker 之上的一個附加元件,用於管理一個基礎架構的容器。另外,在運行 docker-compose 之前,我們需要確保已從伺服器中提取所有程式碼變更、建置應用程式並停止舊版本。為此,我們將使用 bash 腳本。哇...這聽起來很難,我同意。但設定應用程式部署始終是一個乏味且複雜的過程。因此,我們有一個非常好的方案:
  1. 讓我們運行 bash 腳本。
  2. bash 腳本運行 docker-compose。
  3. Docker-compose 使用我們的應用程式啟動一個 docker 容器。
  4. Docker 容器運行我們的應用程式。
現在我們需要確保兩個變數 - 機器人的名稱及其令牌 - 從點 1 到點 4。以便在啟動我們的 java 應用程式時使用這兩個變數。讓我們從結尾到開頭。我們已經知道需要執行什麼命令來啟動 jarnik。因此,我們將配置 Dockerfile,以便它學習接受兩個變數並將它們傳遞給請求。為此,我們將 Dockerfile 簡化為以下形式:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}", "-jar", "/app.jar"]
您可以看到我們新增了兩行並更新了 ENTRYPOINT。線路:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
在編碼器檔案中聲明變數。預設情況下,它們有一個指定的值。如果從這個dockerfile建立映像時,傳遞了這樣名字的環境變量,那麼值就會不同。在 ENTRYPOINT 中,我們加入了更多元素來讀取這些環境變數:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
在這裡您可以看到,在該行內部,使用 ${} 構造,將傳遞 BOT_NAME 和 BOT_TOKEN 的值。接下來,我們需要教導如何接收這些變數並將其傳遞給 docker-compose。

建立 docker-compose.yml

你最好單獨閱讀 YAML 格式,否則這篇文章已經突飛猛進了。對我們來說,這只是 .properties 類型變數的另一種描述。僅在屬性中,它是透過點編寫的,但在 YAML 中,這樣做得更漂亮一些。例如,像這樣。.properties 中的兩個變數: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin 但在 .yaml 中(與 .yml 相同)它將是這樣的:
javarush:
	telegram:
		bot:
		  name: ivan
		  token: pupkin
第二種選擇更美觀、更容易理解。空格應完全如上所示。讓我們以某種方式翻譯我們的 application.properties 和 application.yml 。首先您需要創建它。在專案的根目錄中,建立一個檔案docker-compose.yml並在其中寫入以下內容:
version: '3.1'

services:
 jrtb:
   build:
     context: .
   environment:
     - BOT_NAME=${BOT_NAME}
     - BOT_TOKEN=${BOT_TOKEN}
   restart: always
第一行是 docker-compose 版本。 services:表示此後的所有以下行(將被轉移)引用我們正在配置的服務。到目前為止,我們只有其中一個 - 一個名為jrtb的 Java 應用程式。在它的下面已經是它的所有設定。例如,建置:上下文:。表示我們將在與 docker-compose.yml 相同的目錄中尋找 Dockerfile。但環境:部分將負責確保我們將必要的環境變數傳遞給 Dockerfile。正是我們所需要的。因此,我們在下面傳遞變數。Docker-compose 會在伺服器執行環境變數中尋找它們。讓我們將它們加入 bash 腳本中。

創建 bash 腳本

最後一步是建立 bash 腳本。在專案的根目錄中建立一個名為 start.sh 的文件,並在其中寫入以下內容:
#!/bin/bash

# Pull new changes
git pull

# Prepare Jar
mvn clean
mvn package

# Ensure, that docker-compose stopped
docker-compose stop

# Add environment variables
export BOT_NAME=$1
export BOT_TOKEN=$2

# Start new deployment
docker-compose up --build -d
所有 bash 腳本都需要第一行:沒有它它將無法運作。然後 - 只需在終端機中執行一組命令即可。我在每個命令中添加了註釋,因此應該很清楚。我唯一想解釋的是$1和$2是什麼意思。這是啟動 bash 腳本時將傳遞的兩個變數。使用導出命令,它們將被添加到伺服器變數中並在 docker-compose 中讀取。這適用於 Ubuntu,可能不適用於 Windows,但我不確定。現在您需要新增 stop.sh 腳本,這將停止運作。它將包含幾行:
#!/bin/bash

# Ensure, that docker-compose stopped
docker-compose stop

# Ensure, that the old application won't be deployed again.
mvn clean
在這裡,我們停止 docker-compose 並清理專案 jarnik,該專案自上次建置以來一直存在。我們這樣做是為了確保我們的專案能夠準確地重建。有先例,這就是我添加的原因)結果,我們最終得到了 4 個新文件:
  • Dockerfile - 用於建立應用程式映像的檔案;
  • docker-compose.yml - 一個文件,其中包含我們如何啟動容器的設定;
  • start.sh - 用於部署我們的應用程式的 bash 腳本;
  • stop.sh 是一個用於停止我們的應用程式的 bash 腳本。
我們也將應用程式的版本從 0.2.0-SNAPSHOT 更新到 0.3.0-SNAPSHOT。讓我們在 RELEASE_NOTES 中新增版本的描述,並稍微重構一下其中的內容:
# 發行說明## 0.3.0-SNAPSHOT * JRTB-13:為專案新增部署流程## 0.2.0-SNAPSHOT * JRTB-3:實作用於處理Telegram Bot 指令的指令模式## 0.1.0-SNAPSHOT * JRTB -2:新增存根電報機器人 * JRTB-0:新增 SpringBoot 骨架項目
在自述文件中,我們將新增一個新段落來描述如何部署我們的應用程式:
## 部署部署過程盡可能簡單: 所需軟體: - 用於運行bash 腳本的終端- docker - docker-compose 部署應用程序,切換到所需分支並運行bash 腳本: $ bash start.sh ${bot_username} ${bot_token } 就這樣。
當然,一切都是用英文寫的。像往常一樣,在我們新建立的分支 STEP_4_JRTB-13 中,我們建立一個名為:JRTB-13 的新提交:透過 docker 實現部署過程並推送它。我不再詳細討論我在之前的文章中已經描述過的事情。我不認為重複同樣的事情有什麼意義。再說了,那些自己想出來並做過的人不會有任何疑問。這是我談論如何建立新分支,如何建立提交,如何將提交推送到儲存庫。

底線

今天,我展示了大量新訊息,需要仔細考慮並透過額外閱讀進行擴展。最重要的事情:在一個(!!!)命令的幫助下,部署我們的應用程式所需的一切都將完成。這太酷了,我甚至無法告訴你。是的,我必須在 Docker 文件中花費大量時間來了解如何正確轉送變數。從現在開始,電報機器人將始終在分支的最新版本上運行。 連結到電報機器人。 今天,將不再有適合閱讀的材料連結:責任在於您。你需要學會搜尋資訊。每個訂閱我的電報頻道的人幾乎立即了解到了機器人的部署。朋友們,你們喜歡這個項目嗎?給他一顆星星!這樣它就會變得更受歡迎,更多的人能夠了解它並從中學習。 像往常一樣,我建議在 GitHub 上註冊並關注我的帳戶,以關注本系列以及我在那裡從事的其他專案。 現在我們準備連接資料庫了。下一篇文章會更長,我們將在其中完成使用資料庫所需的一切。所有描述均在JRTB-1

此系列所有資料的清單位於本文開頭。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION