配置說明
本文件說明 AppFuse 應用系統的各項配置選項。
配置架構總覽
後端配置(app-server)
配置檔位置
| 部署方式 | 配置檔位置 |
|---|---|
| Tomcat WAR | $APP_HOME/conf/application.properties |
核心配置
伺服器設定
# 伺服器埠號
server.port=8080
# Context Path(WAR 部署時通常為 /app-server)
server.servlet.context-path=/
# 檔案上傳限制
spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB
資料庫連線
# 通用設定
spring.datasource.username=appfuse
spring.datasource.password=your-password
# JPA 設定
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
MySQL 8.x
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.datasource.url=jdbc:mysql://localhost:3306/appdb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
spring.jpa.properties.hibernate.use_nationalized_character_data=false
PostgreSQL
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:5432/appdb
SQL Server
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.database-platform=org.hibernate.dialect.SQLServerDialect
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=appdb;encrypt=false
Oracle
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.OracleDialect
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:ORCL
H2(開發/測試用)
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.datasource.url=jdbc:h2:mem:appdb
spring.h2.console.enabled=true
安全性配置
# JWT 設定
appfuse.security.token.ttl=86400000
appfuse.security.token.secret=your-secret-key-at-least-32-characters
# 是否停用安全限制(僅開發環境)
appfuse.security.disabled=false
# 登入路徑
appfuse.security.login.path=/login
# 允許匿名存取的路徑(逗號分隔)
appfuse.security.permit=/api/public,/actuator/health
日誌配置
# 日誌等級
logging.level.root=INFO
logging.level.io.leandev.appfuse=DEBUG
logging.level.org.springframework.security=WARN
# 日誌檔案
logging.file.name=/opt/appfuse/logs/app-server.log
logging.file.max-size=100MB
logging.file.max-history=30
# 日誌格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
郵件配置
spring.mail.host=smtp.example.com
spring.mail.port=587
spring.mail.username=noreply@example.com
spring.mail.password=your-password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
Actuator 配置
# 啟用的端點
management.endpoints.web.exposure.include=health,info,metrics,loggers
# 健康檢查詳細資訊
management.endpoint.health.show-details=when-authorized
# 基礎路徑
management.endpoints.web.base-path=/actuator
應用程式目錄
# 應用程式主目錄(可用環境變數 APP_HOME 覆蓋)
app.home=/opt/appfuse
# 文件儲存目錄
app.document.path=${app.home}/data/documents
# 暫存目錄
app.temp.path=${app.home}/data/temp
前端配置(app-web)
配置機制
前端採用「程式碼預設值 + 後端覆蓋」機制,支援部署後動態調整配置:
程式碼預設值
// src/conf/config.ts
export const config: AppEnvironConfig = {
app: {
name: 'App',
version: '1.0.0',
stage: import.meta.env.MODE, // 'development' | 'production'
basename: '/',
baseURL: '/', // API 基礎路徑
msw: {
enabled: import.meta.env.DEV, // 開發環境自動啟用 Mock
},
},
i18n: {
language: 'zh-TW',
fallback: 'en',
languages: ['en', 'zh-TW'],
},
}
後端覆蓋(可選)
生產環境可透過後端 /config endpoint 覆蓋配置,無需重新建置前端:
// GET /config 回應
{
"app": {
"name": "花店管理系統",
"baseURL": "/api/v1",
"msw": {
"enabled": false
}
},
"i18n": {
"language": "zh-TW"
}
}
環境判斷
| 變數 | 開發環境 | 生產環境 | 用途 |
|---|---|---|---|
import.meta.env.DEV | true | false | MSW 預設狀態 |
import.meta.env.MODE | 'development' | 'production' | 環境識別 |
建構時配置
在 vite.config.ts 中可調整建構設定:
export default defineConfig({
build: {
// 輸出目錄
outDir: 'dist',
// 原始碼映射(生產環境建議關閉)
sourcemap: false,
// 程式碼分割
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
router: ['react-router'],
},
},
},
},
});
Nginx 配置
基本配置
/etc/nginx/nginx.conf:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
http {
# 基本設定
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日誌設定
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip 壓縮
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml;
# 檔案上傳限制
client_max_body_size 64M;
# 載入站點配置
include /etc/nginx/sites-enabled/*;
}
站點配置(HTTP)
/etc/nginx/sites-available/appfuse.conf:
server {
listen 80;
server_name your-domain.com;
# 共用的 Proxy 設定
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 檔案上傳限制
client_max_body_size 64M;
# 後端 API 模組
location /app-server/ {
proxy_pass http://127.0.0.1:8080/app-server/;
proxy_buffering off;
}
# 前台 SPA 模組
location /app-web/ {
proxy_pass http://127.0.0.1:8080/app-web/;
proxy_buffering off;
}
# 根路徑重導向至前台
location = / {
return 302 /app-web/;
}
# 禁止存取隱藏檔案
location ~ /\. {
deny all;
}
}
站點配置(HTTPS)
# HTTP 重導向到 HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}
# HTTPS 設定
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL 憑證
ssl_certificate /etc/nginx/ssl/your-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/your-domain.com.key;
# SSL 安全設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# HSTS(建議啟用)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 共用的 Proxy 設定
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 檔案上傳限制
client_max_body_size 64M;
# 後端 API 模組
location /app-server/ {
proxy_pass http://127.0.0.1:8080/app-server/;
proxy_buffering off;
}
# 前台 SPA 模組
location /app-web/ {
proxy_pass http://127.0.0.1:8080/app-web/;
proxy_buffering off;
}
# 根路徑重導向至前台
location = / {
return 302 /app-web/;
}
}
逾時設定
如需調整連線逾時(預設 60 秒):
http {
# 全域逾時設定
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_send_timeout 90;
send_timeout 90;
client_body_timeout 90;
}
進階:檔案傳輸配置注意事項
系統支援兩種檔案傳輸方式,配置需求不同:
-
標準 Multipart 上傳(推薦):
- 效率較高,直接串流傳輸。
- 受
spring.servlet.multipart.max-file-size控制。 - Nginx 與 Tomcat 的
maxPostSize設定需略大於檔案大小即可。
-
JSON 內嵌 Base64 字串上傳:
- 注意:Base64 編碼會使檔案大小膨脹約 33%(100MB 檔案會變成約 133MB 字串)。
- 此方式不視為檔案上傳,而是視為一般 HTTP POST Body。
- Tomcat 設定:必須調整
server.xml中的maxPostSize,數值需設為「檔案大小 x 1.33」。- 注意:Tomcat 預設 2MB,設為 0 或 -1 代表不限制(視版本而定)。
- Nginx 設定:
client_max_body_size同樣需考慮 33% 的膨脹空間。
資料庫配置
MySQL 優化配置
編輯 /etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld]
# 交易隔離等級
transaction-isolation = READ-COMMITTED
# 字元編碼
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 效能調校
max_allowed_packet = 256M
max_connections = 200
# Table 名稱不區分大小寫(需在初始化前設定)
lower_case_table_names = 1
PostgreSQL 優化配置
編輯 postgresql.conf:
# 連線設定
max_connections = 200
# 記憶體設定
shared_buffers = 256MB
work_mem = 16MB
# 日誌設定
log_statement = 'mod'
log_duration = on
繁體中文相容性
編碼需求
本系統需要處理多國語文,特別是繁體中文。各資料庫的編碼設定如下:
| 資料庫 | 字元編碼 | 排序規則 |
|---|---|---|
| MySQL | utf8mb4 | utf8mb4_unicode_ci |
| PostgreSQL | UTF8 | en_US.UTF-8 或 zh_TW.UTF-8 |
| SQL Server | - | Chinese_Taiwan_Stroke_CI_AS |
MySQL 繁體中文配置
MySQL 連線字串必須包含編碼設定:
spring.datasource.url=jdbc:mysql://localhost:3306/appdb?useUnicode=true&characterEncoding=UTF-8&useSSL=false
重要:必須加上以下設定,避免 JPA 使用 nvarchar 導致編碼問題:
spring.jpa.properties.hibernate.use_nationalized_character_data=false
use_nationalized_character_data 設定詳解
這個設定控制 Hibernate/JPA 如何處理 String 類型欄位的資料庫映射。
當設為 true 時:
JPA 會啟用 @Nationalized 註解的行為,預設使用 nvarchar 來建立 String 型別的欄位。但在 MySQL 中,nvarchar 會被轉換為:
varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL
這會強制使用 utf8(3-byte)而非資料庫預設的 utf8mb4(4-byte),導致無法正確儲存某些 Unicode 字元(如罕用字「𩻸」)。
當設為 false 時(建議值):
JPA 會使用標準的 varchar 來建立 String 欄位:
varchar(255) DEFAULT NULL
該欄位會繼承資料庫或表格預設的字元編碼與排序規則。如果資料庫設定為 utf8mb4 和 utf8mb4_unicode_ci,則可正確支援完整的 Unicode 字元集(包括 4-byte 字元)。
範例比較:
| 設定值 | 產生的 SQL | 實際編碼 | 支援 4-byte 字元 |
|---|---|---|---|
true | varchar(255) CHARACTER SET utf8 | utf8 (3-byte) | ❌ |
false | varchar(255) | 繼承資料庫設定 | ✅(若設定 utf8mb4) |
結論:在使用 MySQL 且需要支援繁體中文(特別是罕用字)的環境下,務必將此設定設為
false。
驗證編碼設定
檢查 MySQL 資料庫編碼:
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'appdb';
預期結果:
+----------------------------+------------------------+
| DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+----------------------------+------------------------+
| utf8mb4 | utf8mb4_unicode_ci |
+----------------------------+------------------------+
檢查 SQL Server 編碼:
SELECT name, collation_name FROM sys.databases WHERE name = 'appdb';
相容性測試
使用以下測試字串驗證資料庫是否正確支援繁體中文(包含罕用字):
大林里𩻸魚堀56-1號
說明:「𩻸」是 Unicode 擴展 B 區的罕用字(U+29EF8),需要完整的 UTF-8 4-byte 支援(utf8mb4)才能正確儲存。
測試步驟:
- 新增一筆包含測試字串的資料
- 查詢並確認資料完整顯示
- 確認無亂碼或問號替代字元
環境變數對照表
以下為支援的環境變數及對應的配置項:
| 環境變數 | 配置項 | 說明 |
|---|---|---|
APP_HOME | app.home | 應用程式主目錄 |
SPRING_DATASOURCE_URL | spring.datasource.url | 資料庫連線 URL |
SPRING_DATASOURCE_USERNAME | spring.datasource.username | 資料庫使用者 |
SPRING_DATASOURCE_PASSWORD | spring.datasource.password | 資料庫密碼 |
JAVA_OPTS | - | JVM 參數 |
SERVER_PORT | server.port | 伺服器埠號 |
使用範例
# 設定環境變數
export APP_HOME=/opt/appfuse
export SPRING_DATASOURCE_URL="jdbc:mysql://db.example.com:3306/appdb"
# 啟動應用程式(JAR 方式)
java -jar app-server.jar
# 或透過 Tomcat 啟動(WAR 方式)
$CATALINA_HOME/bin/startup.sh
配置檔範本
開發環境
# application-dev.properties
server.port=8080
spring.datasource.url=jdbc:h2:mem:devdb
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=create-drop
logging.level.io.leandev.appfuse=DEBUG
appfuse.security.disabled=true
測試環境
# application-test.properties
server.port=8080
spring.datasource.url=jdbc:mysql://test-db:3306/testdb
spring.jpa.hibernate.ddl-auto=update
logging.level.root=INFO
appfuse.security.disabled=false
生產環境
# application-prod.properties
server.port=8080
spring.datasource.url=jdbc:mysql://prod-db:3306/proddb
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
logging.level.root=WARN
logging.level.io.leandev.appfuse=INFO
appfuse.security.disabled=false
appfuse.security.token.secret=${JWT_SECRET}
啟用特定環境配置
# 使用環境變數
export SPRING_PROFILES_ACTIVE=prod
java -jar app-server.jar
# 或使用參數
java -jar app-server.jar --spring.profiles.active=prod
下一步
配置完成後,請參閱: