安裝 Spring Boot 應用程式
除了直接使用 java -jar
執行 Spring Boot 應用程式之外,也可以將它們作為 systemd
、init.d
或 Windows 服務執行。
作為 systemd 服務安裝
systemd
是 System V init 系統的後繼者,現在已被許多現代 Linux 發行版使用。Spring Boot 應用程式可以使用 systemd
‘service’ 腳本啟動。
假設您的 Spring Boot 應用程式封裝為 uber jar 在 /var/myapp
中,要將其安裝為 systemd
服務,請建立一個名為 myapp.service
的腳本,並將其放置在 /etc/systemd/system
目錄中。以下腳本提供了一個範例
[Unit]
Description=myapp
After=syslog.target network.target
[Service]
User=myapp
Group=myapp
Type=exec
ExecStart=/path/to/java/home/bin/java -jar /var/myapp/myapp.jar
WorkingDirectory=/var/myapp
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
請記住為您的應用程式變更 Description 、User 、Group 、ExecStart 和 WorkingDirectory 欄位。 |
ExecStart 欄位未宣告腳本動作命令,這表示預設使用 run 命令。 |
執行應用程式的使用者、PID 檔案和主控台記錄檔由 systemd
本身管理,因此必須使用 ‘service’ 腳本中的適當欄位進行組態。請參閱 service unit configuration man page 以取得更多詳細資訊。
若要標記應用程式在系統開機時自動啟動,請使用下列命令
$ systemctl enable myapp.service
執行 man systemctl
以取得更多詳細資訊。
作為 init.d 服務安裝 (System V)
若要將您的應用程式用作 init.d
服務,請組態其建置以產生完全可執行 jar。
完全可執行的 jar 透過在檔案前端嵌入額外的腳本來運作。目前,某些工具不接受此格式,因此您可能不一定能夠使用此技術。例如,jar -xf 可能會靜默地無法解壓縮已設為完全可執行的 jar 或 war。建議您僅在打算直接執行 jar 或 war 時,才將其設為完全可執行,而不是使用 java -jar 執行或將其部署到 servlet 容器。 |
zip64 格式的 jar 檔案無法設為完全可執行。嘗試這樣做將導致 jar 檔案在直接執行或使用 java -jar 執行時回報為損壞。包含一個或多個 zip64 格式巢狀 jar 的標準格式 jar 檔案可以是完全可執行的。 |
若要使用 Maven 建立 ‘完全可執行’ jar,請使用下列外掛程式組態
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
以下範例顯示了等效的 Gradle 組態
tasks.named('bootJar') {
launchScript()
}
然後可以將其符號連結到 init.d
以支援標準的 start
、stop
、restart
和 status
命令。
新增至完全可執行 jar 的預設啟動腳本支援大多數 Linux 發行版,並已在 CentOS 和 Ubuntu 上進行測試。其他平台 (例如 OS X 和 FreeBSD) 需要使用自訂腳本。預設腳本支援以下功能
-
以 jar 檔案擁有者的使用者身分啟動服務
-
使用
/var/run/<appname>/<appname>.pid
追蹤應用程式的 PID -
將主控台記錄寫入
/var/log/<appname>.log
假設您已在 /var/myapp
中安裝 Spring Boot 應用程式,若要將 Spring Boot 應用程式安裝為 init.d
服務,請建立符號連結,如下所示
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
安裝完成後,您可以像往常一樣啟動和停止服務。例如,在基於 Debian 的系統上,您可以使用下列命令啟動它
$ service myapp start
如果您的應用程式無法啟動,請檢查寫入 /var/log/<appname>.log 的記錄檔以尋找錯誤。 |
您也可以使用標準作業系統工具標記應用程式以自動啟動。例如,在 Debian 上,您可以使用下列命令
$ update-rc.d myapp defaults <priority>
保護 init.d 服務
以下是一組關於如何保護作為 init.d 服務執行的 Spring Boot 應用程式的指南。它並非旨在詳盡列出所有應完成以強化應用程式及其執行環境的所有事項。 |
當以 root 身分執行時 (就像使用 root 身分啟動 init.d 服務的情況一樣),預設可執行腳本會以 RUN_AS_USER
環境變數中指定的使用者身分執行應用程式。當未設定環境變數時,將改為使用 jar 檔案的擁有者。您永遠不應以 root
身分執行 Spring Boot 應用程式,因此 RUN_AS_USER
永遠不應為 root,且應用程式的 jar 檔案永遠不應由 root 擁有。相反地,請建立一個特定的使用者來執行您的應用程式,並設定 RUN_AS_USER
環境變數或使用 chown
使其成為 jar 檔案的擁有者,如下列範例所示
$ chown bootapp:bootapp your-app.jar
在這種情況下,預設可執行腳本會以 bootapp
使用者身分執行應用程式。
為了降低應用程式的使用者帳戶被洩漏的風險,您應考慮阻止其使用登入 shell。例如,您可以將帳戶的 shell 設定為 /usr/sbin/nologin 。 |
您也應採取步驟以防止修改應用程式的 jar 檔案。首先,組態其權限,使其無法寫入,且只能由其擁有者讀取或執行,如下列範例所示
$ chmod 500 your-app.jar
其次,您也應採取步驟以限制損害,如果您的應用程式或執行它的帳戶遭到洩漏。如果攻擊者確實獲得了存取權,他們可能會使 jar 檔案可寫入並變更其內容。防止這種情況的一種方法是使用 chattr
使其不可變,如下列範例所示
$ sudo chattr +i your-app.jar
這將阻止任何使用者 (包括 root) 修改 jar。
如果 root 用於控制應用程式的服務,並且您使用 .conf
檔案來自訂其啟動,則 .conf
檔案會由 root 使用者讀取和評估。應相應地保護它。使用 chmod
使檔案只能由擁有者讀取,並使用 chown
使 root 成為擁有者,如下列範例所示
$ chmod 400 your-app.conf
$ sudo chown root:root your-app.conf
自訂啟動腳本
Maven 或 Gradle 外掛程式寫入的預設嵌入式啟動腳本可以通過多種方式進行自訂。對於大多數人來說,使用預設腳本以及一些自訂通常就足夠了。如果您發現無法自訂您需要的內容,請使用 embeddedLaunchScript
選項完全寫入您自己的檔案。
在寫入時自訂啟動腳本
在腳本寫入 jar 檔案時自訂啟動腳本的元素通常是有意義的。例如,init.d 腳本可以提供「描述」。由於您預先知道描述 (且它不需要變更),因此您最好在產生 jar 時提供它。
若要自訂寫入的元素,請使用 Spring Boot Maven 外掛程式的 embeddedLaunchScriptProperties
選項或 Spring Boot Gradle 外掛程式的 launchScript
的 properties
屬性。
預設腳本支援下列屬性替換
名稱 | 描述 | Gradle 預設值 | Maven 預設值 |
---|---|---|---|
|
腳本模式。 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
“INIT INFO” 的 |
|
|
|
|
包含 jar 的資料夾 |
包含 jar 的資料夾 |
|
對應該內嵌在預設啟動腳本中的檔案腳本的參考。這可用於在載入任何外部組態檔之前設定環境變數,例如 |
||
|
|
||
|
|
||
|
|
||
|
|
||
|
當 |
|
|
|
|
60 |
60 |
在執行時自訂腳本
對於需要在寫入 jar 之後自訂的腳本項目,您可以使用環境變數或 組態檔。
預設腳本支援下列環境屬性
變數 | 描述 |
---|---|
|
操作的「模式」。預設值取決於 jar 的建置方式,但通常為 |
|
將用於執行應用程式的使用者。未設定時,將使用 jar 檔案的擁有者。 |
|
當 |
|
pid 資料夾的根名稱 (預設為 |
|
放置記錄檔的資料夾名稱 (預設為 |
|
從中讀取 .conf 檔案的資料夾名稱 (預設與 jar 檔案相同的資料夾)。 |
|
|
|
應用程式的名稱。如果 jar 是從符號連結執行的,則腳本會猜測應用程式名稱。如果它不是符號連結,或者您想明確設定應用程式名稱,這會很有用。 |
|
要傳遞給程式 (Spring Boot 應用程式) 的引數。 |
|
|
|
在啟動 JVM 時傳遞給 JVM 的選項。 |
|
jar 檔案的明確位置,以防腳本用於啟動它實際上未嵌入的 jar。 |
|
如果不為空,則在 shell 程序上設定 |
|
在強制關閉之前,停止應用程式時要等待的時間 (預設為 |
PID_FOLDER 、LOG_FOLDER 和 LOG_FILENAME 變數僅對 init.d 服務有效。對於 systemd ,等效的自訂是透過使用 ‘service’ 腳本完成的。請參閱 service unit configuration man page 以取得更多詳細資訊。 |
使用 Conf 檔案
除了 JARFILE
和 APP_NAME
之外,前一節中列出的設定可以使用 .conf
檔案進行組態。預期該檔案與 jar 檔案位於同一目錄中,並且具有相同的名稱,但後綴為 .conf
而不是 .jar
。例如,名為 /var/myapp/myapp.jar
的 jar 使用名為 /var/myapp/myapp.conf
的組態檔,如下列範例所示
JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder
如果您不喜歡將組態檔放在 jar 檔案旁邊,您可以設定 CONF_FOLDER 環境變數來自訂組態檔的位置。 |
若要了解如何適當地保護此檔案,請參閱保護 init.d 服務的指南。