Java 部署教學:Spring Boot 應用程式部署方案
Java 和 Spring Boot 是企業級應用開發的主力選擇。雖然 Java 應用的啟動時間和記憶體佔用相對較高,但其穩定性、效能和豐富的生態系統,使它在生產環境中廣受歡迎。
這篇教學將帶你從打包 Spring Boot 應用開始,到 Docker 容器化、JVM 調優,最後部署到各大雲端平台。無論你是剛接觸 Java 部署,還是想優化現有的部署流程,都能找到實用的技巧。
如果你想了解更完整的部署策略,可以先閱讀 程式部署完整指南。
Spring Boot 打包基礎

插圖:Spring Boot 打包流程圖
場景描述:
Technical illustration showing Spring Boot 打包流程圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
Spring Boot 最大的特點是可以打包成「可執行的 Fat JAR」,內嵌 Tomcat/Jetty 伺服器,只需要 java -jar 就能執行。
什麼是 Fat JAR
傳統的 Java Web 應用需要部署到 Tomcat 等應用伺服器。但 Spring Boot 的 Fat JAR(或稱 Uber JAR)包含了:
- 你的應用程式碼
- 所有相依的 JAR 檔案
- 內嵌的 Servlet 容器(Tomcat/Jetty/Undertow)
- Spring Boot Loader
這意味著只要有 JRE,就能直接執行:
java -jar my-application.jar
專案結構
典型的 Spring Boot 專案結構:
my-spring-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demo/
│ │ │ ├── DemoApplication.java
│ │ │ ├── controller/
│ │ │ ├── service/
│ │ │ └── repository/
│ │ └── resources/
│ │ ├── application.properties
│ │ ├── application-prod.properties
│ │ └── static/
│ └── test/
├── pom.xml # Maven
├── build.gradle # Gradle
├── Dockerfile
└── README.md
Maven vs Gradle 打包

插圖:Maven vs Gradle 比較圖
場景描述:
Technical illustration showing Maven vs Gradle 比較圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
Spring Boot 支援 Maven 和 Gradle 兩種建置工具,各有優缺點。
Maven 打包
pom.xml 範例:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
打包命令:
# 清理並打包(跳過測試)
mvn clean package -DskipTests
# 打包並執行測試
mvn clean package
# 產出位置
# target/demo-1.0.0.jar
Gradle 打包
build.gradle 範例:
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.example'
version = '1.0.0'
java {
sourceCompatibility = '21'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
打包命令:
# 清理並打包(跳過測試)
./gradlew clean build -x test
# 打包並執行測試
./gradlew clean build
# 產出位置
# build/libs/demo-1.0.0.jar
Maven vs Gradle 比較
| 項目 | Maven | Gradle |
|---|---|---|
| 設定語法 | XML(冗長但明確) | Groovy/Kotlin DSL(簡潔) |
| 建置速度 | 較慢 | 快(增量建置、快取) |
| 學習曲線 | 低 | 中 |
| 生態系統 | 最成熟 | 成長中 |
| 企業使用 | 主流 | 漸增 |
選擇建議:
- 新專案或追求效能 → Gradle
- 企業環境、團隊熟悉 → Maven
💡 VPS 設定太複雜?
Java 應用的部署涉及 JVM 調優、記憶體設定、反向代理等配置。
預約免費諮詢,讓我們幫你處理伺服器設定。
JVM 調優:生產環境設定

插圖:JVM 記憶體模型圖
場景描述:
Technical illustration showing JVM 記憶體模型圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
Java 應用的效能很大程度取決於 JVM 參數設定。正確的調優可以避免 OutOfMemoryError、減少 GC 暫停時間。
記憶體設定
# 基本記憶體設定
java -Xms512m -Xmx1024m -jar app.jar
# 參數說明
# -Xms:初始 Heap 大小
# -Xmx:最大 Heap 大小
記憶體設定建議:
| 可用記憶體 | -Xms | -Xmx | 適用場景 |
|---|---|---|---|
| 1 GB | 256m | 512m | 小型 API |
| 2 GB | 512m | 1024m | 標準應用 |
| 4 GB | 1024m | 2048m | 中型應用 |
| 8 GB+ | 2048m | 4096m | 大型應用 |
重要原則:
- 將 -Xms 和 -Xmx 設為相同值,避免動態調整的開銷
- 不要將 -Xmx 設為 100% 可用記憶體,需保留給 Metaspace、Stack、Native Memory
GC 設定
Java 21 預設使用 G1 GC,適合大多數情況:
# 使用 G1 GC(預設)
java -XX:+UseG1GC -jar app.jar
# 設定 GC 暫停時間目標(毫秒)
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar
# 高吞吐量場景(接受較長暫停)
java -XX:+UseParallelGC -jar app.jar
# 低延遲場景(ZGC,Java 15+)
java -XX:+UseZGC -jar app.jar
完整的生產環境 JVM 參數
java \
-Xms1024m \
-Xmx1024m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/heapdump.hprof \
-Dspring.profiles.active=prod \
-Dserver.port=8080 \
-jar app.jar
| 參數 | 說明 |
|---|---|
| -XX:+HeapDumpOnOutOfMemoryError | OOM 時自動產生 Heap Dump |
| -XX:HeapDumpPath | Heap Dump 存放路徑 |
| -Dspring.profiles.active | Spring Profile |
| -Dserver.port | 應用程式 port |
application.properties 生產設定
# application-prod.properties
# 伺服器設定
server.port=${PORT:8080}
server.shutdown=graceful
# Actuator 健康檢查
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when_authorized
# 連線池設定(HikariCP)
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.connection-timeout=20000
# 日誌設定
logging.level.root=INFO
logging.level.com.example=INFO
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
Docker 容器化部署

插圖:Java Docker 多階段建置圖
場景描述:
Technical illustration showing Java Docker 多階段建置圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
Docker 容器化是 Java 應用部署的最佳實踐,可以確保環境一致性並簡化部署流程。
選擇正確的基礎映像
| 映像 | 大小 | 說明 |
|---|---|---|
| eclipse-temurin:21-jdk | ~450MB | 包含 JDK,用於建置 |
| eclipse-temurin:21-jre | ~270MB | 只有 JRE,用於執行 |
| eclipse-temurin:21-jre-alpine | ~180MB | Alpine 版本,更小 |
| amazoncorretto:21 | ~400MB | Amazon 維護的 OpenJDK |
| azul/zulu-openjdk:21 | ~350MB | Azul 維護的 OpenJDK |
建議:生產環境使用 eclipse-temurin:21-jre-alpine 或 eclipse-temurin:21-jre。
基本 Dockerfile
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
# 複製 JAR 檔案
COPY target/*.jar app.jar
# 開放 port
EXPOSE 8080
# JVM 參數
ENV JAVA_OPTS="-Xms512m -Xmx512m"
# 啟動命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
多階段建置 Dockerfile(推薦)
# 階段一:建置
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
# 複製 Maven 設定(利用 Docker 快取)
COPY pom.xml .
COPY .mvn .mvn
COPY mvnw .
# 下載相依套件(這層會被快取)
RUN ./mvnw dependency:go-offline -B
# 複製原始碼
COPY src src
# 建置(跳過測試)
RUN ./mvnw package -DskipTests -B
# 階段二:執行
FROM eclipse-temurin:21-jre-alpine AS production
WORKDIR /app
# 安全性:建立非 root 使用者
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
# 從建置階段複製 JAR
COPY --from=builder /app/target/*.jar app.jar
# 開放 port
EXPOSE 8080
# 健康檢查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
# JVM 參數
ENV JAVA_OPTS="-Xms512m -Xmx512m -XX:+UseG1GC"
# 啟動命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar"]
Gradle 版本的多階段 Dockerfile
# 階段一:建置
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY build.gradle settings.gradle ./
COPY gradle gradle
COPY gradlew .
RUN ./gradlew dependencies --no-daemon
COPY src src
RUN ./gradlew build -x test --no-daemon
# 階段二:執行
FROM eclipse-temurin:21-jre-alpine AS production
WORKDIR /app
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
ENV JAVA_OPTS="-Xms512m -Xmx512m -XX:+UseG1GC"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
建置並執行
# 建置 Image
docker build -t my-spring-app:1.0.0 .
# 執行容器
docker run -d \
-p 8080:8080 \
-e JAVA_OPTS="-Xms512m -Xmx1024m" \
-e SPRING_PROFILES_ACTIVE=prod \
-e DATABASE_URL=jdbc:postgresql://... \
--name my-app \
my-spring-app:1.0.0
# 查看日誌
docker logs -f my-app
想了解更多 Docker 部署細節,請參考 Docker Deploy 教學。
💡 不確定該選哪個雲端平台?
AWS、GCP、Azure 各有優勢,選錯可能增加成本或維運負擔。
預約免費諮詢,讓專家幫你評估最適合的部署方案。
雲端平台部署

插圖:Java 雲端部署選項圖
場景描述:
Technical illustration showing Java 雲端部署選項圖. Clean, professional diagram style.
視覺重點:
- Clear presentation of the concept
- Professional technical diagram style
- Easy to understand visual elements
必須出現的元素:
- Relevant technical components
- Clear labels and annotations
- Logical flow or structure
需要顯示的中文字:
無
風格:
Clean flat design, technical illustration, modern infographic style
顏色調性:
Professional blues and grays, with accent colors for emphasis
避免元素:
Cluttered design, realistic photos, complex 3D rendering
各大雲端平台都有對 Java/Spring Boot 的良好支援,以下介紹幾種常見的部署方式。
Railway 部署(最簡單)
Railway 會自動偵測 Java 專案並使用正確的 JDK 版本。
1. 建立 system.properties
java.runtime.version=21
2. 連接 GitHub 部署
Railway 會自動執行 mvn clean package 或 gradle build,然後執行 JAR。
3. 設定環境變數
JAVA_OPTS=-Xms512m -Xmx512m
SPRING_PROFILES_ACTIVE=prod
DATABASE_URL=postgresql://...
GCP Cloud Run 部署
# 建置 Docker Image
docker build -t gcr.io/PROJECT_ID/my-spring-app:1.0.0 .
# 推送到 GCR
docker push gcr.io/PROJECT_ID/my-spring-app:1.0.0
# 部署到 Cloud Run
gcloud run deploy my-spring-app \
--image gcr.io/PROJECT_ID/my-spring-app:1.0.0 \
--platform managed \
--region asia-east1 \
--memory 1Gi \
--cpu 1 \
--min-instances 0 \
--max-instances 10 \
--set-env-vars "SPRING_PROFILES_ACTIVE=prod" \
--allow-unauthenticated
Cloud Run 注意事項:
- Java 應用啟動較慢,建議設定 --min-instances 1 避免冷啟動
- 記憶體至少設定 512Mi,建議 1Gi
AWS Elastic Beanstalk 部署
1. 準備 Procfile
web: java -Xms512m -Xmx512m -jar target/demo-1.0.0.jar --server.port=5000
2. 使用 EB CLI 部署
# 初始化
eb init -p java-21-corretto my-spring-app
# 建立環境
eb create production-env
# 部署更新
eb deploy
# 設定環境變數
eb setenv SPRING_PROFILES_ACTIVE=prod DATABASE_URL=jdbc:...
3. 或使用 .ebextensions 設定
# .ebextensions/01-jvm.config
option_settings:
aws:elasticbeanstalk:application:environment:
JAVA_OPTS: "-Xms512m -Xmx1024m -XX:+UseG1GC"
SPRING_PROFILES_ACTIVE: "prod"
Azure App Service 部署
# 安裝 Azure CLI 並登入
az login
# 建立 App Service Plan
az appservice plan create \
--name my-plan \
--resource-group my-group \
--sku B1 \
--is-linux
# 建立 Web App
az webapp create \
--name my-spring-app \
--resource-group my-group \
--plan my-plan \
--runtime "JAVA:21-java21"
# 部署 JAR
az webapp deploy \
--resource-group my-group \
--name my-spring-app \
--src-path target/demo-1.0.0.jar \
--type jar
# 設定環境變數
az webapp config appsettings set \
--resource-group my-group \
--name my-spring-app \
--settings SPRING_PROFILES_ACTIVE=prod
平台比較
| 平台 | 難度 | 費用 | Java 支援 | 適用場景 |
|---|---|---|---|---|
| Railway | ⭐ | $5/月起 | 21 | Side Project、小型應用 |
| Cloud Run | ⭐⭐ | 按用量 | 任意(Docker) | API、微服務 |
| Elastic Beanstalk | ⭐⭐⭐ | 依 EC2 | 21 | 企業應用、AWS 整合 |
| Azure App Service | ⭐⭐ | $13/月起 | 21 | .NET + Java 混合 |
| Kubernetes | ⭐⭐⭐⭐ | 依規模 | 任意 | 大規模、微服務 |
VPS 部署(傳統方式)
如果你需要完全掌控伺服器環境,可以在 VPS 上手動部署。
安裝 Java
# Ubuntu/Debian
sudo apt update
sudo apt install openjdk-21-jre-headless
# Amazon Linux
sudo yum install java-21-amazon-corretto-headless
# 確認安裝
java -version
使用 systemd 管理服務
建立 /etc/systemd/system/my-spring-app.service:
[Unit]
Description=My Spring Boot Application
After=network.target
[Service]
Type=simple
User=spring
Group=spring
Environment="JAVA_OPTS=-Xms512m -Xmx1024m -XX:+UseG1GC"
Environment="SPRING_PROFILES_ACTIVE=prod"
ExecStart=/usr/bin/java $JAVA_OPTS -jar /opt/my-app/app.jar
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=always
RestartSec=10
# 日誌
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
啟動服務:
# 重新載入 systemd
sudo systemctl daemon-reload
# 啟動服務
sudo systemctl start my-spring-app
# 設定開機自動啟動
sudo systemctl enable my-spring-app
# 查看狀態
sudo systemctl status my-spring-app
# 查看日誌
sudo journalctl -u my-spring-app -f
Nginx 反向代理
# /etc/nginx/sites-available/my-spring-app
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支援
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超時設定
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Actuator 端點限制存取
location /actuator {
deny all;
# 或只允許特定 IP
# allow 10.0.0.0/8;
# deny all;
}
}
Spring Boot Actuator 健康檢查
Spring Boot Actuator 提供生產環境必備的監控端點。
啟用 Actuator
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
設定暴露的端點
# application.properties
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when_authorized
management.endpoint.health.probes.enabled=true
健康檢查端點
| 端點 | 用途 |
|---|---|
| /actuator/health | 整體健康狀態 |
| /actuator/health/liveness | 存活探針(K8s 用) |
| /actuator/health/readiness | 就緒探針(K8s 用) |
| /actuator/info | 應用程式資訊 |
| /actuator/metrics | 指標數據 |
FAQ 常見問題
Q1: Spring Boot 啟動太慢怎麼辦?
- 使用 Spring Boot 3.2+ 的 Virtual Threads
- 使用 GraalVM Native Image(大幅加速啟動)
- 減少不必要的 Auto-Configuration
- 使用 lazy initialization
spring.main.lazy-initialization=true
Q2: 記憶體不足(OOM)怎麼處理?
- 增加
-Xmx設定 - 檢查是否有記憶體洩漏
- 使用
-XX:+HeapDumpOnOutOfMemoryError產生 dump 分析 - 檢查連線池設定是否過大
Q3: 如何優雅關閉(Graceful Shutdown)?
# application.properties
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
Q4: Docker 中 Java 應用記憶體設定?
Java 10+ 會自動偵測容器記憶體限制。但建議明確設定:
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0"
這會使用容器記憶體限制的 75% 作為最大 Heap。
Q5: 如何實現零停機部署?
- Kubernetes:使用 Rolling Update 策略
- Elastic Beanstalk:使用 Rolling 或 Immutable 更新
- 傳統 VPS:使用 Nginx upstream + 兩個實例輪換
Java Spring Boot 部署方案重點整理
這篇教學涵蓋了 Java/Spring Boot 應用的完整部署流程:
- 打包方式:Maven vs Gradle 的差異與使用
- JVM 調優:記憶體設定、GC 選擇、生產環境參數
- Docker 容器化:多階段建置、基礎映像選擇
- 雲端部署:Railway、Cloud Run、Elastic Beanstalk、Azure
- VPS 部署:systemd 服務、Nginx 反向代理
Java 應用雖然啟動較慢、記憶體佔用較高,但其穩定性和效能在生產環境中經得起考驗。選擇合適的部署方式,配合正確的 JVM 調優,就能讓你的 Spring Boot 應用穩定運行。
如果你想了解如何在 Kubernetes 上部署 Java 應用,可以接著閱讀 Kubernetes Deploy 教學。
☕ Java 部署需要協助?
從 JVM 調優到雲端架構規劃,Java 生產部署有許多專業細節。
預約免費諮詢,讓 VibeFix 的工程師幫你把 Spring Boot 專案順利上線!