跳至主要内容

配置說明

本文件說明 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.DEVtruefalseMSW 預設狀態
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;
}

進階:檔案傳輸配置注意事項

系統支援兩種檔案傳輸方式,配置需求不同:

  1. 標準 Multipart 上傳(推薦)

    • 效率較高,直接串流傳輸。
    • spring.servlet.multipart.max-file-size 控制。
    • Nginx 與 Tomcat 的 maxPostSize 設定需略大於檔案大小即可。
  2. 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

繁體中文相容性

編碼需求

本系統需要處理多國語文,特別是繁體中文。各資料庫的編碼設定如下:

資料庫字元編碼排序規則
MySQLutf8mb4utf8mb4_unicode_ci
PostgreSQLUTF8en_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

該欄位會繼承資料庫或表格預設的字元編碼與排序規則。如果資料庫設定為 utf8mb4utf8mb4_unicode_ci,則可正確支援完整的 Unicode 字元集(包括 4-byte 字元)。

範例比較

設定值產生的 SQL實際編碼支援 4-byte 字元
truevarchar(255) CHARACTER SET utf8utf8 (3-byte)
falsevarchar(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)才能正確儲存。

測試步驟:

  1. 新增一筆包含測試字串的資料
  2. 查詢並確認資料完整顯示
  3. 確認無亂碼或問號替代字元

環境變數對照表

以下為支援的環境變數及對應的配置項:

環境變數配置項說明
APP_HOMEapp.home應用程式主目錄
SPRING_DATASOURCE_URLspring.datasource.url資料庫連線 URL
SPRING_DATASOURCE_USERNAMEspring.datasource.username資料庫使用者
SPRING_DATASOURCE_PASSWORDspring.datasource.password資料庫密碼
JAVA_OPTS-JVM 參數
SERVER_PORTserver.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

下一步

配置完成後,請參閱: