在前幾篇中,我們已完成:
模組 | 服務 | Port | 用途 |
---|---|---|---|
React 前端 | http://localhost:5173 |
開發用 | 顯示 UI、發送 API |
Node.js 後端 | http://localhost:3000 |
API | 提供資料與驗證 |
Swagger 文件 | http://localhost:3000/api-docs |
文件頁面 | 測試與說明 API |
1️⃣ CORS 問題
前端在 5173、後端在 3000,跨來源請求被瀏覽器封鎖。
2️⃣ 網址不一致
不同服務使用不同 Port,切換環境時需手動調整設定。
3️⃣ 部署複雜
上線需為多個服務設定網域與 SSL,維運成本高。
Nginx 可將所有請求集中至單一入口,統一轉發至對應服務。
優點:
✅ 統一 Domain 與 Port
✅ 消除 CORS 問題
✅ 簡化部署與維運
Nginx 讓前端、後端與文件共用同一個乾淨入口。
Nginx 是一個超高效能的 Web 伺服器。
它可以:
功能 | 說明 |
---|---|
🌐 Web Server | 提供靜態檔案(HTML、CSS、JS) |
🔁 Reverse Proxy | 將請求轉發給內部 API 服務 |
⚙️ Load Balancer | 分流流量到多台伺服器 |
今天只用它的 反向代理(Reverse Proxy) 功能。
類型 | 說明 | 例子 |
---|---|---|
🔹 正向代理 (Forward Proxy) | 幫使用者去對外請求(隱藏使用者) | VPN、Proxy 伺服器 |
🔸 反向代理 (Reverse Proxy) | 幫外部請求轉送到內部伺服器(隱藏伺服器) | Nginx、API Gateway |
舉例來說,反向代理就像是:
你只知道公司的電話(Domain),不知道各部門的分機(Port)。
總機小姐會根據你的需求(URL),幫你轉接到正確的部門(後端服務)。
使用者永遠只看到 Nginx,而不會知道真正的伺服器在哪裡。
[Client Browser]
│
▼
┌────────────────────────────┐
│ Nginx │ ← 反向代理層
├────────────────────────────┤
│ │ │
│ ▼ │
│ /auth → backend:3000 │
│ /posts → backend:3000 │
│ /api-docs → backend:3000 │
│ / → frontend:5173 │
└────────────────────────────┘
nginx.conf
server {
listen 80;
server_name localhost;
# ------------------------
# 後端 API Proxy
# ------------------------
location ^~ /auth {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location ^~ /posts {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Swagger UI 文件
location /api-docs/ {
proxy_pass http://backend:3000/api-docs/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# ------------------------
# React 前端(開發用容器)
# ------------------------
location / {
proxy_pass http://frontend:5173;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
}
}
由於每個人的開發環境不同,本篇採用 Docker 容器化 進行示範,
方便快速建立一致的前後端整合架構。
backEnd/Dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
frontEnd/Dockerfile
(不打包,直接啟動開發伺服器)
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev"]
version: '3.9'
services:
backend:
build: ./backEnd
container_name: rbac_backend
ports:
- "3000:3000"
environment:
- MONGO_URL=mongodb://mongo:27017/rbacDB
- JWT_SECRET=MY_SUPER_SECRET
depends_on:
- mongo
frontend:
build: ./frontEnd
container_name: rbac_frontend
ports:
- "5173:5173"
depends_on:
- backend
mongo:
image: mongo:6
container_name: rbac_mongo
volumes:
- mongo_data:/data/db
nginx:
image: nginx:alpine
container_name: rbac_nginx
ports:
- "8080:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- backend
- frontend
volumes:
mongo_data:
docker compose up -d --build
啟動後:
http://localhost:8080 → React 前端頁面
http://localhost:8080/auth → API 登入
http://localhost:8080/posts → 取得貼文列表
http://localhost:8080/api-docs/ → Swagger 文件
測試項目 | 測試 URL | 預期結果 |
---|---|---|
使用者登入 | http://localhost:8080/auth/login | 200 OK ✅ |
取得貼文列表 | http://localhost:8080/posts | 200 OK ✅ |
Swagger UI | http://localhost:8080/api-docs/ | 顯示 Swagger UI ✅ |
前端首頁 | http://localhost:8080 | 顯示 React 畫面 ✅ |
如果你在本地開發(沒跑容器),
請把 Nginx 的設定改成指向 localhost
:
location ^~ /auth {
proxy_pass http://localhost:3000;
}
location ^~ /posts {
proxy_pass http://localhost:3000;
}
location ^~ /api-docs {
proxy_pass http://localhost:3000;
}
location / {
proxy_pass http://localhost:5173;
}
Nginx 不只是 Web Server,更是現代前後端架構的「統一入口」。
它負責串聯前端、後端、文件、資料庫,讓整個系統在同一個 Domain 下協作運行。
功能 | 效果 |
---|---|
統一入口 | 所有服務共享同一個網址,前後端結構更清晰 |
消除 CORS | 前後端同源訪問,跨域問題自然解決 |
隱藏內部結構 | API 與資料庫不對外暴露,提升安全性 |
簡化部署流程 | 集中管理 Proxy、SSL、日誌設定 |
這次的範例程式篇幅較多,如果你想直接執行或參考完整專案架構,
可前往以下 GitHub Repo 下載並運行:
可實際跑起來體驗整個權限系統