跳至主要内容

部署策略總覽

本文檔說明花店管理系統的部署策略與選項。

部署架構

選項一:分離部署(推薦用於生產環境)

前後端獨立部署:

┌─────────────────┐
│ Nginx (443) │ 前端靜態檔案托管 + 反向代理
└────────┬────────┘

┌────┴────┐
│ │
▼ ▼
┌───────┐ ┌────────────────┐
│ SPA │ │ Spring Boot │ 後端 API
│(靜態)│ │ (8080) │
└───────┘ └────────────────┘

優點

  • 前後端獨立擴展
  • 可以使用 CDN 加速前端
  • 前後端獨立部署,互不影響

部署步驟

  1. 前端部署(Nginx):
# 建置前端
cd app-web
npm run build

# 部署到 Nginx
cp -r dist/* /var/www/florist/
  1. 後端部署(Spring Boot):
# 建置後端
cd app-server
./gradlew clean build

# 執行
java -jar build/libs/app-server-0.0.1-SNAPSHOT.jar

詳細說明:生產環境部署

選項二:統一部署(推薦用於內部系統)

使用 app-web-host 將前端打包到 Spring Boot WAR:

┌────────────────────────┐
│ Spring Boot WAR │
│ ┌──────────────────┐ │
│ │ /api/* │ │ REST API
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ /* │ │ SPA (index.html)
│ └──────────────────┘ │
└────────────────────────┘

優點

  • 單一 WAR 部署,簡化運維
  • 自動處理 SPA 路由轉發
  • 統一的 CORS 配置

部署步驟

# 1. 建置前端
cd app-web
npm run build

# 2. 複製到 app-web-host
cp -r dist/* ../app-web-host/src/main/resources/static/

# 3. 建置 WAR
cd ../app-web-host
./gradlew clean build

# 4. 部署
cp build/libs/app-web-host.war /opt/tomcat/webapps/

詳細說明:統一部署

環境配置

開發環境

  • 前端http://localhost:5173(Vite Dev Server)
  • 後端http://localhost:8080(Spring Boot)
  • 資料庫:PostgreSQL(Docker 或本地)

測試環境

  • 前端https://florist-staging.leandev.io
  • 後端https://api-staging.leandev.io
  • 資料庫:PostgreSQL(RDS)

生產環境

  • 前端https://florist.leandev.io
  • 後端https://api.leandev.io
  • 資料庫:PostgreSQL(RDS,多可用區)

環境變數

前端環境變數

不同環境使用不同的 .env 檔案:

# .env.development(開發環境)
VITE_API_BASE_URL=http://localhost:8080
VITE_ENABLE_MOCK_API=true

# .env.staging(測試環境)
VITE_API_BASE_URL=https://api-staging.leandev.io
VITE_ENABLE_MOCK_API=false

# .env.production(生產環境)
VITE_API_BASE_URL=https://api.leandev.io
VITE_ENABLE_MOCK_API=false

建置時指定環境:

# 測試環境建置
npm run build -- --mode staging

# 生產環境建置
npm run build -- --mode production

後端環境變數

使用 Spring Profiles:

# application.yml(共用配置)
spring:
application:
name: florist

# application-dev.yml(開發環境)
spring:
datasource:
url: jdbc:postgresql://localhost:5432/florist_dev

# application-staging.yml(測試環境)
spring:
datasource:
url: ${DATABASE_URL} # 從環境變數讀取

# application-prod.yml(生產環境)
spring:
datasource:
url: ${DATABASE_URL}
jpa:
show-sql: false # 生產環境不顯示 SQL

啟動時指定 Profile:

# 開發環境
./gradlew bootRun

# 測試環境
java -jar app-server.jar --spring.profiles.active=staging

# 生產環境
java -jar app-server.jar --spring.profiles.active=prod

資料庫管理

Flyway 遷移

自動執行資料庫遷移:

# 執行遷移
./gradlew flywayMigrate -Pflyway.url=jdbc:postgresql://prod-db/florist

# 查看遷移狀態
./gradlew flywayInfo

# 驗證遷移
./gradlew flywayValidate

備份策略

  • 自動備份:每日凌晨 2:00(RDS 自動備份)
  • 手動備份:重大更新前
  • 備份保留:30 天

監控與日誌

應用程式監控

使用 Spring Boot Actuator:

# application-prod.yml
management:
endpoints:
web:
exposure:
include: health,metrics,info
endpoint:
health:
show-details: always

監控端點:

  • GET /actuator/health - 健康檢查
  • GET /actuator/metrics - 應用程式指標
  • GET /actuator/info - 應用程式資訊

日誌管理

# application-prod.yml
logging:
level:
root: INFO
io.leandev.appfuse.app: INFO
file:
name: /var/log/florist/application.log
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

CI/CD 流程

GitLab CI/CD

# .gitlab-ci.yml
stages:
- test
- build
- deploy

test:
stage: test
script:
- ./gradlew test
- npm run test

build:
stage: build
script:
- ./gradlew clean build
- npm run build
artifacts:
paths:
- build/libs/*.jar
- dist/

deploy:staging:
stage: deploy
environment:
name: staging
script:
- scp build/libs/*.jar deploy@staging:/opt/app/
- ssh deploy@staging 'systemctl restart florist'
only:
- develop

deploy:production:
stage: deploy
environment:
name: production
script:
- scp build/libs/*.jar deploy@prod:/opt/app/
- ssh deploy@prod 'systemctl restart florist'
only:
- main
when: manual

健康檢查

前端健康檢查

Nginx 配置:

location /health {
return 200 "OK";
add_header Content-Type text/plain;
}

後端健康檢查

Spring Boot Actuator:

curl https://api.leandev.io/actuator/health

# 回應:
{
"status": "UP",
"components": {
"db": {
"status": "UP"
}
}
}

下一步