362 lines
6.8 KiB
Markdown
362 lines
6.8 KiB
Markdown
# Vercel 部署配置指南
|
||
|
||
## 前置準備
|
||
|
||
### 1. Vercel 帳號設置
|
||
1. 訪問 [Vercel](https://vercel.com)
|
||
2. 使用 GitHub 帳號登入
|
||
3. 授權 Vercel 訪問你的 GitHub repositories
|
||
|
||
### 2. 專案準備
|
||
確保專案已推送到 GitHub:
|
||
```bash
|
||
git add .
|
||
git commit -m "準備部署到 Vercel"
|
||
git push origin main
|
||
```
|
||
|
||
## 部署步驟
|
||
|
||
### Step 1: 導入專案
|
||
1. 在 Vercel Dashboard 點擊 "New Project"
|
||
2. 選擇 GitHub repository: `dramaling-vocab-learning`
|
||
3. 點擊 "Import"
|
||
|
||
### Step 2: 配置專案
|
||
```yaml
|
||
Framework Preset: Next.js
|
||
Root Directory: ./
|
||
Build Command: npm run build
|
||
Output Directory: .next
|
||
Install Command: npm install
|
||
```
|
||
|
||
### Step 3: 環境變數設置
|
||
在 "Environment Variables" 區域添加:
|
||
|
||
```env
|
||
# Supabase
|
||
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
|
||
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
||
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
|
||
|
||
# Gemini AI
|
||
GEMINI_API_KEY=your_gemini_api_key
|
||
|
||
# App Configuration
|
||
NEXT_PUBLIC_APP_URL=https://your-domain.vercel.app
|
||
NODE_ENV=production
|
||
```
|
||
|
||
### Step 4: 部署設置
|
||
點擊 "Deploy" 開始首次部署
|
||
|
||
## vercel.json 配置
|
||
|
||
```json
|
||
{
|
||
"framework": "nextjs",
|
||
"buildCommand": "npm run build",
|
||
"devCommand": "npm run dev",
|
||
"installCommand": "npm install",
|
||
"regions": ["sin1"],
|
||
"headers": [
|
||
{
|
||
"source": "/api/(.*)",
|
||
"headers": [
|
||
{
|
||
"key": "Cache-Control",
|
||
"value": "no-store, max-age=0"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"source": "/(.*)",
|
||
"headers": [
|
||
{
|
||
"key": "X-Content-Type-Options",
|
||
"value": "nosniff"
|
||
},
|
||
{
|
||
"key": "X-Frame-Options",
|
||
"value": "DENY"
|
||
},
|
||
{
|
||
"key": "X-XSS-Protection",
|
||
"value": "1; mode=block"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"rewrites": [
|
||
{
|
||
"source": "/api/:path*",
|
||
"destination": "/api/:path*"
|
||
}
|
||
],
|
||
"functions": {
|
||
"app/api/ai/generate-flashcard/route.ts": {
|
||
"maxDuration": 30
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 域名配置
|
||
|
||
### 1. 添加自定義域名
|
||
1. 在專案設置中選擇 "Domains"
|
||
2. 輸入你的域名 (例如: dramaling.com)
|
||
3. 選擇添加方式:
|
||
- 使用 Vercel DNS (推薦)
|
||
- 使用外部 DNS
|
||
|
||
### 2. DNS 配置
|
||
如果使用外部 DNS,添加以下記錄:
|
||
|
||
```
|
||
Type: A
|
||
Name: @
|
||
Value: 76.76.21.21
|
||
|
||
Type: CNAME
|
||
Name: www
|
||
Value: cname.vercel-dns.com
|
||
```
|
||
|
||
### 3. SSL 證書
|
||
Vercel 自動提供並更新 SSL 證書
|
||
|
||
## 性能優化配置
|
||
|
||
### 1. Edge Functions
|
||
```typescript
|
||
// app/api/edge/route.ts
|
||
export const runtime = 'edge'
|
||
export const dynamic = 'force-dynamic'
|
||
|
||
export async function GET() {
|
||
// Edge function 邏輯
|
||
}
|
||
```
|
||
|
||
### 2. ISR (增量靜態再生)
|
||
```typescript
|
||
// app/page.tsx
|
||
export const revalidate = 3600 // 1小時重新驗證
|
||
```
|
||
|
||
### 3. 圖片優化
|
||
```typescript
|
||
// next.config.mjs
|
||
module.exports = {
|
||
images: {
|
||
domains: ['your-supabase-url.supabase.co'],
|
||
formats: ['image/avif', 'image/webp'],
|
||
},
|
||
}
|
||
```
|
||
|
||
## 監控設置
|
||
|
||
### 1. Vercel Analytics
|
||
```bash
|
||
npm i @vercel/analytics
|
||
```
|
||
|
||
```typescript
|
||
// app/layout.tsx
|
||
import { Analytics } from '@vercel/analytics/react'
|
||
|
||
export default function RootLayout({ children }) {
|
||
return (
|
||
<html>
|
||
<body>
|
||
{children}
|
||
<Analytics />
|
||
</body>
|
||
</html>
|
||
)
|
||
}
|
||
```
|
||
|
||
### 2. Speed Insights
|
||
```bash
|
||
npm i @vercel/speed-insights
|
||
```
|
||
|
||
```typescript
|
||
// app/layout.tsx
|
||
import { SpeedInsights } from '@vercel/speed-insights/next'
|
||
|
||
export default function RootLayout({ children }) {
|
||
return (
|
||
<html>
|
||
<body>
|
||
{children}
|
||
<SpeedInsights />
|
||
</body>
|
||
</html>
|
||
)
|
||
}
|
||
```
|
||
|
||
## CI/CD 配置
|
||
|
||
### 1. 自動部署
|
||
- **Production**: main 分支自動部署
|
||
- **Preview**: 所有 PR 自動生成預覽環境
|
||
|
||
### 2. 部署保護
|
||
```yaml
|
||
# 在 Vercel Dashboard 設置
|
||
Protection Rules:
|
||
- Deployment Protection: Enabled
|
||
- Password Protection: Optional
|
||
- Trusted IPs: Configure if needed
|
||
```
|
||
|
||
### 3. GitHub Actions 整合
|
||
```yaml
|
||
# .github/workflows/preview.yml
|
||
name: Vercel Preview Deployment
|
||
|
||
on:
|
||
pull_request:
|
||
types: [opened, synchronize]
|
||
|
||
jobs:
|
||
deploy:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v3
|
||
- uses: amondnet/vercel-action@v25
|
||
with:
|
||
vercel-token: ${{ secrets.VERCEL_TOKEN }}
|
||
vercel-args: '--prod'
|
||
vercel-org-id: ${{ secrets.ORG_ID}}
|
||
vercel-project-id: ${{ secrets.PROJECT_ID}}
|
||
```
|
||
|
||
## 環境管理
|
||
|
||
### 開發環境
|
||
```env
|
||
# .env.development
|
||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||
NEXT_PUBLIC_API_ENDPOINT=http://localhost:3000/api
|
||
```
|
||
|
||
### 預覽環境
|
||
```env
|
||
# 在 Vercel Dashboard 設置
|
||
Environment: Preview
|
||
NEXT_PUBLIC_APP_URL=https://preview.dramaling.vercel.app
|
||
```
|
||
|
||
### 生產環境
|
||
```env
|
||
# 在 Vercel Dashboard 設置
|
||
Environment: Production
|
||
NEXT_PUBLIC_APP_URL=https://dramaling.com
|
||
```
|
||
|
||
## 故障排除
|
||
|
||
### 常見問題
|
||
|
||
#### 1. Build 失敗
|
||
```bash
|
||
# 檢查本地 build
|
||
npm run build
|
||
|
||
# 清理快取
|
||
rm -rf .next node_modules
|
||
npm install
|
||
npm run build
|
||
```
|
||
|
||
#### 2. 環境變數未生效
|
||
- 確認變數名稱以 `NEXT_PUBLIC_` 開頭(前端使用)
|
||
- 重新部署專案
|
||
- 檢查環境變數範圍(Development/Preview/Production)
|
||
|
||
#### 3. 函數超時
|
||
```json
|
||
// vercel.json
|
||
{
|
||
"functions": {
|
||
"app/api/slow-endpoint/route.ts": {
|
||
"maxDuration": 60
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 4. CORS 錯誤
|
||
```typescript
|
||
// app/api/route.ts
|
||
export async function GET(request: Request) {
|
||
return new Response('Hello', {
|
||
headers: {
|
||
'Access-Control-Allow-Origin': '*',
|
||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
||
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
||
},
|
||
})
|
||
}
|
||
```
|
||
|
||
## 效能監控
|
||
|
||
### Core Web Vitals
|
||
目標值:
|
||
- LCP (Largest Contentful Paint): < 2.5s
|
||
- FID (First Input Delay): < 100ms
|
||
- CLS (Cumulative Layout Shift): < 0.1
|
||
|
||
### 優化建議
|
||
1. 使用 `next/dynamic` 進行代碼分割
|
||
2. 優化圖片大小和格式
|
||
3. 實施適當的快取策略
|
||
4. 最小化 JavaScript bundle 大小
|
||
|
||
## 回滾策略
|
||
|
||
### 快速回滾
|
||
1. 在 Vercel Dashboard 選擇 "Deployments"
|
||
2. 找到之前的穩定版本
|
||
3. 點擊 "..." 選單
|
||
4. 選擇 "Promote to Production"
|
||
|
||
### Git 回滾
|
||
```bash
|
||
# 回滾到特定 commit
|
||
git revert <commit-hash>
|
||
git push origin main
|
||
|
||
# 或重置到之前的 commit
|
||
git reset --hard <commit-hash>
|
||
git push origin main --force
|
||
```
|
||
|
||
## 成本優化
|
||
|
||
### 免費方案限制
|
||
- 100GB 頻寬/月
|
||
- 100 小時 Build 時間/月
|
||
- 12 個團隊成員
|
||
|
||
### 優化建議
|
||
1. 使用 ISR 減少服務器負載
|
||
2. 實施邊緣快取
|
||
3. 優化圖片和資源
|
||
4. 監控函數執行時間
|
||
|
||
## 安全最佳實踐
|
||
|
||
1. **環境變數加密**: 所有敏感資料通過環境變數管理
|
||
2. **HTTPS 強制**: 自動重定向 HTTP 到 HTTPS
|
||
3. **安全標頭**: 配置適當的安全響應標頭
|
||
4. **訪問控制**: 使用 Vercel 的訪問控制功能
|
||
5. **日誌審計**: 定期審查部署和訪問日誌 |