部署策略總覽
本文檔說明花店管理系統的部署策略與選項。
部署架構
選項一:分離部署(推薦用於生產環境)
前後端獨立部署:
┌─────────────────┐
│ Nginx (443) │ 前端靜態檔案托管 + 反向代理
└────────┬────────┘
│
┌────┴────┐
│ │
▼ ▼
┌───────┐ ┌────────────────┐
│ SPA │ │ Spring Boot │ 後端 API
│(靜態)│ │ (8080) │
└───────┘ └────────────────┘
優點:
- 前後端獨立擴展
- 可以使用 CDN 加速前端
- 前後端獨立部署,互不影響
部署步驟:
- 前端部署(Nginx):
# 建置前端
cd app-web
npm run build
# 部署到 Nginx
cp -r dist/* /var/www/florist/
- 後端部署(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"
}
}
}