安裝 Spring Boot 應用程式

除了直接使用 java -jar 執行 Spring Boot 應用程式之外,也可以將它們作為 systemdinit.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
請記住為您的應用程式變更 DescriptionUserGroupExecStartWorkingDirectory 欄位。
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 以支援標準的 startstoprestartstatus 命令。

新增至完全可執行 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 外掛程式的 launchScriptproperties 屬性

預設腳本支援下列屬性替換

名稱 描述 Gradle 預設值 Maven 預設值

mode

腳本模式。

auto

auto

initInfoProvides

“INIT INFO” 的 Provides 區段

${task.baseName}

${project.artifactId}

initInfoRequiredStart

“INIT INFO” 的 Required-Start 區段。

$remote_fs $syslog $network

$remote_fs $syslog $network

initInfoRequiredStop

“INIT INFO” 的 Required-Stop 區段。

$remote_fs $syslog $network

$remote_fs $syslog $network

initInfoDefaultStart

“INIT INFO” 的 Default-Start 區段。

2 3 4 5

2 3 4 5

initInfoDefaultStop

“INIT INFO” 的 Default-Stop 區段。

0 1 6

0 1 6

initInfoShortDescription

“INIT INFO” 的 Short-Description 區段。

${project.description} 的單行版本 (回退到 ${task.baseName})

${project.name}

initInfoDescription

“INIT INFO” 的 Description 區段。

${project.description} (回退到 ${task.baseName})

${project.description} (回退到 ${project.name})

initInfoChkconfig

“INIT INFO” 的 chkconfig 區段

2345 99 01

2345 99 01

confFolder

CONF_FOLDER 的預設值

包含 jar 的資料夾

包含 jar 的資料夾

inlinedConfScript

對應該內嵌在預設啟動腳本中的檔案腳本的參考。這可用於在載入任何外部組態檔之前設定環境變數,例如 JAVA_OPTS

logFolder

LOG_FOLDER 的預設值。僅對 init.d 服務有效

logFilename

LOG_FILENAME 的預設值。僅對 init.d 服務有效

pidFolder

PID_FOLDER 的預設值。僅對 init.d 服務有效

pidFilename

PID_FOLDER 中 PID 檔案名稱的預設值。僅對 init.d 服務有效

useStartStopDaemon

start-stop-daemon 命令可用時,是否應使用它來控制程序

true

true

stopWaitTime

STOP_WAIT_TIME 的預設值,以秒為單位。僅對 init.d 服務有效

60

60

在執行時自訂腳本

對於需要在寫入 jar 之後自訂的腳本項目,您可以使用環境變數或 組態檔

預設腳本支援下列環境屬性

變數 描述

MODE

操作的「模式」。預設值取決於 jar 的建置方式,但通常為 auto (表示它會嘗試透過檢查它是否是名為 init.d 的目錄中的符號連結來猜測它是否是 init 腳本)。您可以將其明確設定為 service,以便 stop|start|status|restart 命令可以運作,或者如果您想在前景色中執行腳本,則設定為 run

RUN_AS_USER

將用於執行應用程式的使用者。未設定時,將使用 jar 檔案的擁有者。

USE_START_STOP_DAEMON

start-stop-daemon 命令可用時,是否應使用它來控制程序。預設為 true

PID_FOLDER

pid 資料夾的根名稱 (預設為 /var/run)。

LOG_FOLDER

放置記錄檔的資料夾名稱 (預設為 /var/log)。

CONF_FOLDER

從中讀取 .conf 檔案的資料夾名稱 (預設與 jar 檔案相同的資料夾)。

LOG_FILENAME

LOG_FOLDER 中記錄檔的名稱 (預設為 <appname>.log)。

APP_NAME

應用程式的名稱。如果 jar 是從符號連結執行的,則腳本會猜測應用程式名稱。如果它不是符號連結,或者您想明確設定應用程式名稱,這會很有用。

RUN_ARGS

要傳遞給程式 (Spring Boot 應用程式) 的引數。

JAVA_HOME

java 可執行檔的位置預設使用 PATH 探索,但如果 $JAVA_HOME/bin/java 中有可執行檔,您可以明確設定它。

JAVA_OPTS

在啟動 JVM 時傳遞給 JVM 的選項。

JARFILE

jar 檔案的明確位置,以防腳本用於啟動它實際上未嵌入的 jar。

DEBUG

如果不為空,則在 shell 程序上設定 -x 旗標,讓您可以查看腳本中的邏輯。

STOP_WAIT_TIME

在強制關閉之前,停止應用程式時要等待的時間 (預設為 60 秒)。

PID_FOLDERLOG_FOLDERLOG_FILENAME 變數僅對 init.d 服務有效。對於 systemd,等效的自訂是透過使用 ‘service’ 腳本完成的。請參閱 service unit configuration man page 以取得更多詳細資訊。
使用 Conf 檔案

除了 JARFILEAPP_NAME 之外,前一節中列出的設定可以使用 .conf 檔案進行組態。預期該檔案與 jar 檔案位於同一目錄中,並且具有相同的名稱,但後綴為 .conf 而不是 .jar。例如,名為 /var/myapp/myapp.jar 的 jar 使用名為 /var/myapp/myapp.conf 的組態檔,如下列範例所示

myapp.conf
JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder
如果您不喜歡將組態檔放在 jar 檔案旁邊,您可以設定 CONF_FOLDER 環境變數來自訂組態檔的位置。

若要了解如何適當地保護此檔案,請參閱保護 init.d 服務的指南

Microsoft Windows 服務

Spring Boot 應用程式可以使用 winsw 作為 Windows 服務啟動。

一個 (單獨維護的範例) 逐步描述了如何為您的 Spring Boot 應用程式建立 Windows 服務。