-----------tencent first conmit------------
Some checks failed
Deploy to Production / deploy (push) Failing after 6m19s

This commit is contained in:
魏风
2026-03-11 15:56:11 +08:00
parent 4c63a663ac
commit 84aa601243
7 changed files with 782 additions and 1 deletions

47
.env.production.example Normal file
View File

@@ -0,0 +1,47 @@
# =============================================================================
# 生产环境配置 — 复制为 .env.production 并填入真实值
# =============================================================================
# Domain
DOMAIN=makefire.fun
# Frontend host (用于后端生成邮件链接等)
FRONTEND_HOST=https://makefire.fun
# Environment
ENVIRONMENT=production
PROJECT_NAME="Full Stack FastAPI Project"
STACK_NAME=full-stack-fastapi-project
# Backend
BACKEND_CORS_ORIGINS="https://makefire.fun,https://api.makefire.fun"
# ⚠️ 必须修改:运行 openssl rand -hex 32 生成
SECRET_KEY=changethis
FIRST_SUPERUSER=admin@makefire.fun
# ⚠️ 必须修改:设置强密码
FIRST_SUPERUSER_PASSWORD=changethis
# Emails (可选,如不需要发送邮件可留空)
SMTP_HOST=
SMTP_USER=
SMTP_PASSWORD=
EMAILS_FROM_EMAIL=info@makefire.fun
SMTP_TLS=True
SMTP_SSL=False
SMTP_PORT=587
# Postgres — 连接 1Panel 已有的 PostgreSQL 容器
# 在 Docker 网络 1panel-network 内,主机名为 postgresql
POSTGRES_SERVER=postgresql
POSTGRES_PORT=5432
POSTGRES_DB=app
# ⚠️ 使用已有 PG 的凭据,或为本项目创建专用用户
POSTGRES_USER=user_ZPKMQ6
POSTGRES_PASSWORD=password_CYmsGt
SENTRY_DSN=
# Docker images (本地构建,不需要远程 registry)
DOCKER_IMAGE_BACKEND=backend
DOCKER_IMAGE_FRONTEND=frontend

View File

@@ -0,0 +1,79 @@
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Create .env.production from secrets
run: |
cat > .env.production << 'ENVEOF'
DOMAIN=${{ secrets.DOMAIN }}
FRONTEND_HOST=${{ secrets.FRONTEND_HOST }}
ENVIRONMENT=production
PROJECT_NAME=${{ secrets.PROJECT_NAME }}
STACK_NAME=${{ secrets.STACK_NAME }}
BACKEND_CORS_ORIGINS=${{ secrets.BACKEND_CORS_ORIGINS }}
SECRET_KEY=${{ secrets.SECRET_KEY }}
FIRST_SUPERUSER=${{ secrets.FIRST_SUPERUSER }}
FIRST_SUPERUSER_PASSWORD=${{ secrets.FIRST_SUPERUSER_PASSWORD }}
SMTP_HOST=${{ secrets.SMTP_HOST }}
SMTP_USER=${{ secrets.SMTP_USER }}
SMTP_PASSWORD=${{ secrets.SMTP_PASSWORD }}
EMAILS_FROM_EMAIL=${{ secrets.EMAILS_FROM_EMAIL }}
SMTP_TLS=${{ secrets.SMTP_TLS }}
SMTP_SSL=${{ secrets.SMTP_SSL }}
SMTP_PORT=${{ secrets.SMTP_PORT }}
POSTGRES_SERVER=${{ secrets.POSTGRES_SERVER }}
POSTGRES_PORT=${{ secrets.POSTGRES_PORT }}
POSTGRES_DB=${{ secrets.POSTGRES_DB }}
POSTGRES_USER=${{ secrets.POSTGRES_USER }}
POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
DOCKER_IMAGE_BACKEND=${{ secrets.DOCKER_IMAGE_BACKEND }}
DOCKER_IMAGE_FRONTEND=${{ secrets.DOCKER_IMAGE_FRONTEND }}
ENVEOF
- name: Build Docker images
run: docker compose -f compose.prod.yml build
- name: Stop existing services
run: docker compose -f compose.prod.yml down --remove-orphans || true
- name: Start services
run: docker compose -f compose.prod.yml up -d
- name: Wait for backend health check
run: |
echo "Waiting for backend to be healthy..."
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:8000/api/v1/utils/health-check/ > /dev/null 2>&1; then
echo "✅ Backend is healthy!"
exit 0
fi
echo "Attempt $i/30 - waiting 10s..."
sleep 10
done
echo "❌ Backend health check failed after 300s"
docker compose -f compose.prod.yml logs backend
exit 1
- name: Verify frontend
run: |
if curl -sf http://127.0.0.1:3001 > /dev/null 2>&1; then
echo "✅ Frontend is accessible!"
else
echo "❌ Frontend is not accessible"
docker compose -f compose.prod.yml logs frontend
exit 1
fi
- name: Cleanup old Docker images
run: docker image prune -f || true

3
.gitignore vendored
View File

@@ -5,3 +5,6 @@ node_modules/
/playwright-report/
/blob-report/
/playwright/.cache/
.DS_Store
.env.production
.venv/

View File

@@ -42,4 +42,4 @@ RUN --mount=type=cache,target=/root/.cache/uv \
WORKDIR /app/backend/
CMD ["fastapi", "run", "--workers", "4", "app/main.py"]
CMD ["fastapi", "run", "--workers", "2", "app/main.py"]

89
compose.prod.yml Normal file
View File

@@ -0,0 +1,89 @@
services:
prestart:
image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
build:
context: .
dockerfile: backend/Dockerfile
networks:
- 1panel-network
command: bash scripts/prestart.sh
env_file:
- .env.production
environment:
- DOMAIN=${DOMAIN}
- FRONTEND_HOST=${FRONTEND_HOST?Variable not set}
- ENVIRONMENT=${ENVIRONMENT}
- BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS}
- SECRET_KEY=${SECRET_KEY?Variable not set}
- FIRST_SUPERUSER=${FIRST_SUPERUSER?Variable not set}
- FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD?Variable not set}
- SMTP_HOST=${SMTP_HOST}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}
- EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL}
- POSTGRES_SERVER=${POSTGRES_SERVER}
- POSTGRES_PORT=${POSTGRES_PORT}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER?Variable not set}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- SENTRY_DSN=${SENTRY_DSN}
backend:
image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
restart: always
networks:
- 1panel-network
depends_on:
prestart:
condition: service_completed_successfully
ports:
- "127.0.0.1:8000:8000"
env_file:
- .env.production
environment:
- DOMAIN=${DOMAIN}
- FRONTEND_HOST=${FRONTEND_HOST?Variable not set}
- ENVIRONMENT=${ENVIRONMENT}
- BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS}
- SECRET_KEY=${SECRET_KEY?Variable not set}
- FIRST_SUPERUSER=${FIRST_SUPERUSER?Variable not set}
- FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD?Variable not set}
- SMTP_HOST=${SMTP_HOST}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}
- EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL}
- POSTGRES_SERVER=${POSTGRES_SERVER}
- POSTGRES_PORT=${POSTGRES_PORT}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER?Variable not set}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- SENTRY_DSN=${SENTRY_DSN}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"]
interval: 10s
timeout: 5s
retries: 5
build:
context: .
dockerfile: backend/Dockerfile
frontend:
image: '${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}'
restart: always
networks:
- 1panel-network
ports:
- "127.0.0.1:3001:80"
build:
context: .
dockerfile: frontend/Dockerfile
args:
- VITE_API_URL=https://api.${DOMAIN?Variable not set}
- NODE_ENV=production
networks:
1panel-network:
external: true

452
deploy-tencent.md Normal file
View File

@@ -0,0 +1,452 @@
# 部署指南:腾讯云 + 1Panel + OpenResty + Gitea CI/CD
## 目录
1. [架构概览](#1-架构概览)
2. [服务器准备](#2-服务器准备)
3. [配置环境变量](#3-配置环境变量)
4. [创建数据库](#4-创建数据库)
5. [手动首次部署](#5-手动首次部署)
6. [在 1Panel 中配置 OpenResty](#6-在-1panel-中配置-openresty)
7. [DNS 解析配置](#7-dns-解析配置)
8. [配置 Gitea Actions CI/CD](#8-配置-gitea-actions-cicd)
9. [验证部署](#9-验证部署)
10. [日常运维](#10-日常运维)
---
## 1. 架构概览
```
用户浏览器
OpenResty (1Panel 管理, SSL, 端口 80/443)
├── makefire.fun → 127.0.0.1:3001 (Frontend Nginx 容器)
└── api.makefire.fun → 127.0.0.1:8000 (Backend FastAPI 容器)
PostgreSQL (1Panel 已有容器, 1panel-network)
```
**关键设计决策:**
- 后端和前端容器只绑定 `127.0.0.1`,不对外暴露,由 OpenResty 统一反代
- 所有容器加入 `1panel-network`,可直接通过 `postgresql` 主机名访问已有数据库
- 不使用 Traefik用 1Panel 自带的 OpenResty 替代)
- 不启动独立 PostgreSQL 容器(复用已有的)
---
## 2. 服务器准备
### 2.1 创建部署目录
```bash
# SSH 登录服务器后执行
sudo mkdir -p /opt/fastapi-app
sudo chown $USER:$USER /opt/fastapi-app
```
### 2.2 初始化 Git 仓库(在 Gitea 上)
1. 登录 Gitea`http://your-server-ip:3000`
2. 创建新仓库,例如 `full-stack-fastapi`
3. 在本地开发机上添加 Gitea 远程仓库:
```bash
cd /Users/weifeng/Workspace/full-stack-fastapi-template
# 添加 Gitea 远程
git remote add gitea http://your-server-ip:3000/your-username/full-stack-fastapi.git
# 推送代码
git push gitea main
```
---
## 3. 配置环境变量
### 3.1 在服务器上创建生产环境文件
```bash
cd /opt/fastapi-app
# 复制示例文件(首次需要从代码仓库获取)
cp .env.production.example .env.production
```
### 3.2 修改关键配置
```bash
nano .env.production
```
**必须修改的项:**
```bash
# 生成强随机密钥
SECRET_KEY=$(openssl rand -hex 32)
echo "生成的 SECRET_KEY: $SECRET_KEY"
# 设置强管理员密码
FIRST_SUPERUSER_PASSWORD=你的强密码
```
> ⚠️ `SECRET_KEY` 和 `FIRST_SUPERUSER_PASSWORD` 不能使用默认值 `changethis`,否则生产环境会报错。
---
## 4. 创建数据库
在已有的 PostgreSQL 中为本项目创建专用数据库:
```bash
# 方法一:使用 docker exec
docker exec -it 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 -c "CREATE DATABASE app;"
# 验证数据库是否创建成功
docker exec -it 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 -c "\l" | grep app
```
如果你想创建专用用户(更安全,可选):
```bash
docker exec -it 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 -c "
CREATE USER fastapi_user WITH PASSWORD 'your_strong_password';
GRANT ALL PRIVILEGES ON DATABASE app TO fastapi_user;
ALTER DATABASE app OWNER TO fastapi_user;
"
```
> 如果使用专用用户,记得更新 `.env.production` 中的 `POSTGRES_USER` 和 `POSTGRES_PASSWORD`。
---
## 5. 手动首次部署
### 5.1 克隆代码到服务器
```bash
cd /opt/fastapi-app
git clone http://localhost:3000/your-username/full-stack-fastapi.git .
# 或者如果已经有代码
git pull origin main
```
### 5.2 复制环境变量文件
确保 `.env.production``/opt/fastapi-app/` 目录下。
### 5.3 构建和启动
```bash
cd /opt/fastapi-app
# 构建镜像
docker compose -f compose.prod.yml build
# 启动服务
docker compose -f compose.prod.yml up -d
# 查看日志
docker compose -f compose.prod.yml logs -f
```
### 5.4 验证容器状态
```bash
# 查看运行状态
docker compose -f compose.prod.yml ps
# 测试后端
curl http://127.0.0.1:8000/api/v1/utils/health-check/
# 测试前端
curl -I http://127.0.0.1:3001
```
---
## 6. 在 1Panel 中配置 OpenResty
### 6.1 创建前端网站
1. 打开 1Panel → **网站****创建网站**
2. 选择 **反向代理**
3. 配置:
- **主域名**: `makefire.fun`
- **代理地址**: `http://127.0.0.1:3001`
4. 点击创建
### 6.2 创建后端 API 网站
1. **网站****创建网站****反向代理**
2. 配置:
- **主域名**: `api.makefire.fun`
- **代理地址**: `http://127.0.0.1:8000`
3. 点击创建
### 6.3 配置 SSL 证书
对每个网站:
1. 点击网站名称进入设置
2. 选择 **HTTPS** 标签
3. 选择 **申请证书****Let's Encrypt**
4. 勾选 **自动续签**
5. 勾选 **HTTP → HTTPS 强制跳转**
### 6.4 修改后端网站配置(可选优化)
进入 `api.makefire.fun` 网站设置 → **配置文件**,在 `location /` 块中添加:
```nginx
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 请求体大小限制
client_max_body_size 10m;
# 超时
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
```
> 完整参考配置见项目根目录的 `openresty-example.conf`。
---
## 7. DNS 解析配置
在你的域名 DNS 管理处(腾讯云 DNS 或其他)添加:
| 记录类型 | 主机记录 | 记录值 | TTL |
|---------|---------|--------|-----|
| A | @ | 你的服务器 IP | 600 |
| A | api | 你的服务器 IP | 600 |
> 如果使用腾讯云域名,进入 **DNS 解析 DNSPod** 配置。
---
## 8. 配置 Gitea Actions CI/CD
### 8.1 安装 Gitea Actions Runner
```bash
# 1. 下载 Gitea Actions Runner
# 访问 https://gitea.com/gitea/act_runner/releases 获取最新版本
wget https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64
chmod +x act_runner-0.2.11-linux-amd64
sudo mv act_runner-0.2.11-linux-amd64 /usr/local/bin/act_runner
# 2. 生成配置文件
cd /opt
act_runner generate-config > act_runner_config.yaml
```
### 8.2 修改 Runner 配置
编辑 `/opt/act_runner_config.yaml`,关键修改:
```yaml
runner:
# 标签,决定 workflow 中 runs-on 可以匹配的值
labels:
- "ubuntu-latest:host"
# ↑ 使用 host 模式,直接在服务器上运行(不在 Docker 中套 Docker
```
> **为什么用 `host` 模式?** 因为 workflow 需要执行 `docker compose` 命令来管理服务器上的容器。若在容器中运行,需要额外配置 Docker-in-Docker对低内存服务器更加不友好。
### 8.3 注册 Runner
```bash
# 1. 在 Gitea 中获取 Runner Token
# 进入仓库 → Settings → Actions → Runners → 点击 "Create new runner"
# 复制显示的 Token
# 2. 注册
act_runner register \
--instance http://localhost:3000 \
--token YOUR_RUNNER_TOKEN \
--name my-runner \
--labels "ubuntu-latest:host" \
--config /opt/act_runner_config.yaml \
--no-interactive
# 3. 启动(测试)
act_runner daemon --config /opt/act_runner_config.yaml
```
### 8.4 设置为系统服务(推荐)
```bash
sudo tee /etc/systemd/system/gitea-runner.service << 'EOF'
[Unit]
Description=Gitea Actions Runner
After=network.target docker.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/fastapi-app
ExecStart=/usr/local/bin/act_runner daemon --config /opt/act_runner_config.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable gitea-runner
sudo systemctl start gitea-runner
# 查看状态
sudo systemctl status gitea-runner
```
### 8.5 配置 Gitea Secrets
在 Gitea 仓库中配置环境变量密钥:
1. 进入仓库 → **Settings****Actions****Secrets**
2. 添加以下 Secrets
| Secret 名称 | 值 |
|-------------|-----|
| `DOMAIN` | `makefire.fun` |
| `FRONTEND_HOST` | `https://makefire.fun` |
| `PROJECT_NAME` | `Full Stack FastAPI Project` |
| `STACK_NAME` | `full-stack-fastapi-project` |
| `BACKEND_CORS_ORIGINS` | `https://makefire.fun,https://api.makefire.fun` |
| `SECRET_KEY` | *(用 `openssl rand -hex 32` 生成)* |
| `FIRST_SUPERUSER` | `admin@makefire.fun` |
| `FIRST_SUPERUSER_PASSWORD` | *(你的强密码)* |
| `SMTP_HOST` | *(留空或填写)* |
| `SMTP_USER` | *(留空或填写)* |
| `SMTP_PASSWORD` | *(留空或填写)* |
| `EMAILS_FROM_EMAIL` | `info@makefire.fun` |
| `SMTP_TLS` | `True` |
| `SMTP_SSL` | `False` |
| `SMTP_PORT` | `587` |
| `POSTGRES_SERVER` | `postgresql` |
| `POSTGRES_PORT` | `5432` |
| `POSTGRES_DB` | `app` |
| `POSTGRES_USER` | `user_ZPKMQ6` |
| `POSTGRES_PASSWORD` | `password_CYmsGt` |
| `SENTRY_DSN` | *(留空)* |
| `DOCKER_IMAGE_BACKEND` | `backend` |
| `DOCKER_IMAGE_FRONTEND` | `frontend` |
### 8.6 启用 Gitea Actions
1. 进入仓库 → **Settings****Repository**
2. 确保 **Actions** 功能已启用
3. 如果 Gitea 全局未启用 Actions需要在 Gitea 配置文件中添加:
```ini
; 在 /opt/1panel/apps/gitea/gitea/data/gitea/conf/app.ini 中
[actions]
ENABLED = true
```
修改后重启 Gitea 容器:
```bash
docker restart 1Panel-gitea-FSXv
```
---
## 9. 验证部署
### 9.1 本地访问测试
```bash
# 后端健康检查
curl http://127.0.0.1:8000/api/v1/utils/health-check/
# 前端页面
curl -I http://127.0.0.1:3001
```
### 9.2 域名访问测试
```bash
# 前端
curl -I https://makefire.fun
# 后端 API 文档
curl -I https://api.makefire.fun/docs
# 后端健康检查
curl https://api.makefire.fun/api/v1/utils/health-check/
```
### 9.3 CI/CD 测试
```bash
# 在本地开发机上
cd /Users/weifeng/Workspace/full-stack-fastapi-template
echo "# test" >> README.md
git add .
git commit -m "test: trigger CI/CD"
git push gitea main
```
然后在 Gitea 仓库的 **Actions** 标签中查看运行状态。
---
## 10. 日常运维
### 查看日志
```bash
cd /opt/fastapi-app
docker compose -f compose.prod.yml logs -f backend # 后端日志
docker compose -f compose.prod.yml logs -f frontend # 前端日志
docker compose -f compose.prod.yml logs -f # 全部日志
```
### 重启服务
```bash
docker compose -f compose.prod.yml restart backend
docker compose -f compose.prod.yml restart frontend
```
### 手动重新部署
```bash
cd /opt/fastapi-app
git pull origin main
docker compose -f compose.prod.yml build
docker compose -f compose.prod.yml down
docker compose -f compose.prod.yml up -d
```
### 清理 Docker 资源
```bash
# 清理无用镜像(释放磁盘空间)
docker image prune -f
docker system prune -f
```
### 数据库备份
```bash
# 备份
docker exec 1Panel-postgresql-bxrK pg_dump -U user_ZPKMQ6 app > backup_$(date +%Y%m%d).sql
# 恢复
docker exec -i 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 app < backup_20260311.sql
```

111
openresty-example.conf Normal file
View File

@@ -0,0 +1,111 @@
# =============================================================================
# OpenResty / Nginx 反向代理配置示例
# 此文件仅供参考,实际配置在 1Panel 网站管理中完成
# =============================================================================
#
# 在 1Panel 中需要创建 2 个网站:
# 1. makefire.fun → 前端
# 2. api.makefire.fun → 后端 API
#
# 两个网站都需要:
# - 开启 SSL (1Panel 可自动申请 Let's Encrypt 证书)
# - 开启 HTTP → HTTPS 强制跳转
#
# 以下是每个网站的反向代理配置内容:
# =============================================
# 网站 1: makefire.fun (前端)
# =============================================
# 在 1Panel 中: 网站 → 创建网站 → 反向代理
# 代理地址: http://127.0.0.1:3001
server {
listen 80;
listen 443 ssl http2;
server_name makefire.fun;
# SSL 证书 (由 1Panel 自动管理,以下路径仅为示例)
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/key.pem;
# HTTP → HTTPS 跳转
if ($scheme = http) {
return 301 https://$host$request_uri;
}
# 前端反向代理
location / {
proxy_pass http://127.0.0.1:3001;
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;
# SPA 路由支持 — 当后端 nginx 返回 404 时,由前端处理
proxy_intercept_errors on;
error_page 404 = /index.html;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
}
# =============================================
# 网站 2: api.makefire.fun (后端 API)
# =============================================
# 在 1Panel 中: 网站 → 创建网站 → 反向代理
# 代理地址: http://127.0.0.1:8000
server {
listen 80;
listen 443 ssl http2;
server_name api.makefire.fun;
# SSL 证书 (由 1Panel 自动管理)
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/key.pem;
# HTTP → HTTPS 跳转
if ($scheme = http) {
return 301 https://$host$request_uri;
}
# API 反向代理
location / {
proxy_pass http://127.0.0.1:8000;
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;
# WebSocket 支持 (如后续需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 请求体大小限制 (文件上传等)
client_max_body_size 10m;
}
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}