如果是在开发环境中的运行方法:
在一个终端中 , 启动后端
fastapi run api/main.py
打开另一个终端,启动前端:
npm run dev
项目打包生产环境正式部署方法:
要将 Vue 前端和 FastAPI 后端部署在同一台电脑上,并充分利用多 CPU 且避免跨域问题,最简便的方法是使用 反向代理 和 进程管理器。以下是详细步骤和解释:
- 项目准备:
-
Vue 前端:
- 确保你的 Vue 项目已经构建(
npm run build
),生成dist
目录(或其他配置的输出目录)。 - Vue 项目中与后端 API 交互时,使用相对路径(例如
/api/users
)或环境变量配置的基础 URL。不要硬编码后端地址和端口。
- 确保你的 Vue 项目已经构建(
-
FastAPI 后端:
- 确保你的 FastAPI 应用可以正常运行。
- FastAPI 应用监听一个端口(例如 8000)。
- 安装和配置 Nginx (反向代理):
Nginx 是一个高性能的 Web 服务器和反向代理服务器。我们将使用它来:
提供 Vue 前端的静态文件服务。
将前端发出的 API 请求转发到 FastAPI 后端。
处理跨域问题。
-
安装 Nginx:
- Windows: 下载 Nginx for Windows ,解压到你喜欢的目录。
- macOS: 使用 Homebrew 安装:
brew install nginx
- Linux (Ubuntu/Debian):
sudo apt update && sudo apt install nginx
- Linux (CentOS/RHEL):
sudo yum install epel-release && sudo yum install nginx
-
配置 Nginx:
-
找到 Nginx 的配置文件:
- Windows:
conf/nginx.conf
(在 Nginx 解压目录下) - macOS:
/usr/local/etc/nginx/nginx.conf
(或/opt/homebrew/etc/nginx/nginx.conf
,取决于 Homebrew 安装位置) - Linux:
/etc/nginx/nginx.conf
或/etc/nginx/conf.d/default.conf
- Windows:
修改配置文件 (nginx.conf): 用以下内容替换或修改
server
块:
server { listen 80; # 监听 80 端口 (HTTP 默认端口) server_name localhost; # 或你的域名 (如果部署到服务器) # Vue 前端静态文件 location / { root /path/to/your/vue/dist; # 替换为你的 Vue 项目 dist 目录的绝对路径 index index.html; try_files $uri $uri/ /index.html; # 处理 Vue Router 的 history 模式 } # FastAPI 后端 API 代理 location /api { proxy_pass http://127.0.0.1:8000; # 转发到 FastAPI 后端 (假设 FastAPI 监听 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; } # 可选: 启用 gzip 压缩 (提高性能) gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml+rss text/javascript; }
-
关键配置解释:
-
listen 80;
: Nginx 监听 80 端口,这是 HTTP 的默认端口。你可以根据需要更改。 -
root /path/to/your/vue/dist;
: 指定 Vue 构建后的dist
目录的绝对路径。 -
try_files $uri $uri/ /index.html;
: 这是处理 Vue Router 使用 history 模式的关键。它确保所有非文件请求都重定向到index.html
,由 Vue Router 处理。 -
location /api
: 定义一个以/api
开头的 URL 路径。 -
proxy_pass http://127.0.0.1:8000;
: 将/api
开头的请求转发到 FastAPI 后端,假设 FastAPI 运行在本地的 8000 端口。 -
proxy_set_header ...
: 设置一些请求头,以便后端可以获取客户端的真实 IP 地址等信息。 -
gzip on;
: 启用 gzip 压缩,可以减少传输的数据量,提高性能。
-
-
测试 Nginx 配置:
- Windows: 在 Nginx 目录下打开命令行,运行
nginx -t
- macOS/Linux:
sudo nginx -t
- 如果没有错误,继续下一步。
- Windows: 在 Nginx 目录下打开命令行,运行
-
启动/重启 Nginx:
- Windows: 双击
nginx.exe
启动,或在命令行运行nginx
。 要重启,运行nginx -s reload
。 - macOS:
brew services start nginx
(启动) 或brew services restart nginx
(重启) - Linux:
sudo systemctl start nginx
(启动) 或sudo systemctl restart nginx
(重启)
- Windows: 双击
-
- 使用 Uvicorn (或 Gunicorn) 和进程管理器启动 FastAPI:
Uvicorn 是一个 ASGI 服务器,用于运行 FastAPI 应用。Gunicorn 是一个 WSGI/ASGI 服务器,可以管理多个 Uvicorn 进程,充分利用多 CPU。
-
安装 Uvicorn 和 Gunicorn (如果尚未安装):
pip install uvicorn gunicorn
-
启动 FastAPI (使用 Uvicorn):
uvicorn your_app_module:app --host 0.0.0.0 --port 8000 --reload # 开发环境
-
your_app_module
: 你的 FastAPI 应用的主模块文件 (例如main.py
,则写main
)。 -
app
: 你的 FastAPI 应用实例的名称 (通常是app = FastAPI()
)。 -
--host 0.0.0.0
: 监听所有网络接口 (重要,这样 Nginx 才能通过 127.0.0.1 访问)。 -
--port 8000
: FastAPI 监听的端口 (与 Nginx 配置中的proxy_pass
对应)。 -
--reload
: (可选) 启用代码热重载,方便开发。
-
-
启动 FastAPI (使用 Gunicorn, 充分利用多 CPU):
gunicorn your_app_module:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
-
-w 4
: 启动 4 个 worker 进程 (根据你的 CPU 核心数调整)。 -
-k uvicorn.workers.UvicornWorker
: 指定使用 Uvicorn worker。 -
-b 0.0.0.0:8000
: 绑定到所有接口的 8000 端口。
更推荐的方式:使用进程管理器(如
pm2
(Node.js) 或supervisor
(Python))来管理 Gunicorn 进程,可以实现自动重启、日志管理等功能。-
使用 pm2 (Node.js 环境):
- 全局安装 pm2:
npm install -g pm2
- 启动 FastAPI:
pm2 start "gunicorn your_app_module:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000" --name fastapi-app
- 保存当前进程列表:
pm2 save
- 设置开机自启:
pm2 startup
(按照提示操作)
- 全局安装 pm2:
-
使用 Supervisor (Python 环境):
安装 Supervisor:
pip install supervisor
-
创建 Supervisor 配置文件 (例如
supervisord.conf
):[program:fastapi-app] command=gunicorn your_app_module:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 directory=/path/to/your/fastapi/project ; FastAPI 项目目录 autostart=true autorestart=true stderr_logfile=/var/log/fastapi-app.err.log stdout_logfile=/var/log/fastapi-app.out.log
启动 Supervisor:
supervisord -c supervisord.conf
使用
supervisorctl
管理进程 (例如supervisorctl status
,supervisorctl restart fastapi-app
)。 配置开机自启通常需要将supervisord
添加到系统服务。
-
- 访问你的应用:
现在,你应该可以通过浏览器访问 http://localhost
(或 http://localhost:80
,如果 Nginx 监听的是 80 端口) 来访问你的 Vue 前端。前端发出的以 /api
开头的请求会被 Nginx 转发到 FastAPI 后端,不会有跨域问题。
总结:
这种部署方式的优点:
- 简便: 只需要配置 Nginx 和一个进程管理器。
- 高性能: Nginx 处理静态文件非常高效,Gunicorn/Uvicorn 可以充分利用多 CPU。
- 无跨域问题: 前端和后端通过 Nginx 在同一个域名下提供服务,避免了跨域。
- 易于扩展: 如果需要部署到服务器,只需要将 Nginx 配置中的
server_name
改为你的域名,并将代码部署到服务器即可。 - 生产环境就绪: 使用了生产环境推荐的服务器和进程管理器
重要提示:
- 确保防火墙允许 80 端口 (或你配置的 Nginx 端口) 的流量。
- 在生产环境中,建议使用 HTTPS (配置 SSL 证书)。
- 根据你的实际情况调整 Nginx 和 Gunicorn/Uvicorn 的配置。
- 强烈建议使用进程管理器 (pm2 或 Supervisor) 来管理 FastAPI 进程。
- 如果你的前端项目使用了其他的 URL 路径(不仅仅是
/api
)与后端交互,你需要在 Nginx 配置中添加相应的location
块进行代理。 - Windows下,如果遇到路径问题,可以尝试使用双反斜杠
\\
或正斜杠/
来表示路径。
这个方案是经过实践验证的,非常适合将 Vue 和 FastAPI 部署在同一台机器上。
如果从其他电脑访问部署在 IP 地址为 192.168.61.3 的服务,Vue 和 FastAPI 代码中不需要写明这个 IP 地址。关键在于 Nginx 的配置和前端 API 请求的写法。
- Nginx 配置 (无需修改):
你之前在 Nginx 的 nginx.conf
中的配置:
server {
listen 80;
server_name localhost; # 这里保持 localhost 或改为 192.168.61.3 都可以
location / {
root /path/to/your/vue/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://127.0.0.1:8000;
# ... 其他 proxy_set_header ...
}
}
-
server_name
: 这里可以保持localhost
,也可以改为192.168.61.3
。localhost
只在服务器本机访问时有效,而192.168.61.3
可以从局域网内的其他电脑访问。 更推荐的做法是:- 开发环境: 保持
localhost
。 - 局域网测试/部署: 改为
192.168.61.3
(或服务器的实际 IP)。 - 生产环境 (有域名): 改为你的域名 (例如
example.com
)。
- 开发环境: 保持
proxy_pass http://127.0.0.1:8000;
: 这个配置非常重要。它告诉 Nginx 将/api
开头的请求转发到 服务器本机 的 8000 端口。 因为 FastAPI 是在服务器上运行的,所以 Nginx 总是通过127.0.0.1
(本地回环地址) 来访问 FastAPI,无论外部客户端从哪个 IP 地址访问。
- Vue 代码 (使用相对路径或环境变量):
在 Vue 代码中,与后端 API 交互时,不要硬编码任何 IP 地址或端口。使用以下两种方式之一:
-
相对路径 (推荐):
// 假设你的 API 基础路径是 /api fetch('/api/users') .then(response => response.json()) .then(data => console.log(data)); // 或者使用 axios axios.get('/api/users') .then(response => console.log(response.data));
这种方式最简单,也最灵活。因为 Nginx 已经配置了
/api
路径的代理,所以 Vue 发出的/api/users
请求会被 Nginx 自动转发到 FastAPI。 -
环境变量 (更灵活):
在 Vue 项目的根目录下创建
.env
文件 (或.env.development
,.env.production
等,根据你的环境)。-
在
.env
文件中定义一个变量:VUE_APP_API_BASE_URL=/api
或者,如果你想在开发环境和生产环境使用不同的基础URL,可以这样:
.env.development
:VUE_APP_API_BASE_URL=/api
.env.production
:VUE_APP_API_BASE_URL=/api # 或者,如果生产环境的 API 基础路径不同,可以修改
-
在 Vue 代码中使用这个变量:
const apiBaseUrl = process.env.VUE_APP_API_BASE_URL; fetch(`${apiBaseUrl}/users`) .then(response => response.json()) .then(data => console.log(data)); // 或者使用 axios axios.get(`${apiBaseUrl}/users`) .then(response => console.log(response.data));
使用环境变量的好处是,你可以根据不同的环境 (开发、测试、生产) 轻松切换 API 的基础 URL,而无需修改代码。
- FastAPI 代码 (无需修改):
FastAPI 代码中不需要做任何修改。它只需要监听本地的 8000 端口 (或其他你配置的端口),并通过 Uvicorn/Gunicorn 启动即可。
- 客户端访问:
其他电脑上的用户,只需要在浏览器中输入服务器地址就可以访问你的 Vue 应用。 Vue 应用发出的 API 请求会被 Nginx 转发到 FastAPI,整个过程对客户端是透明的。
总结:
- Nginx 作为反向代理,负责将客户端请求转发到正确的后端服务。
- Vue 代码使用相对路径或环境变量来构建 API 请求,不依赖于具体的 IP 地址。
- FastAPI 只需要监听本地端口。
- 客户端通过服务器的 IP 地址访问 Nginx,Nginx 再将请求转发到 FastAPI。
这种架构使得你的应用部署非常灵活,无论是在本地开发、局域网测试,还是部署到远程服务器,都不需要修改 Vue 或 FastAPI 的代码。只需要修改 Nginx 的 server_name
和 Vue 的环境变量 (如果需要) 即可。
在这种部署方式下(使用 Nginx 反向代理),FastAPI 后端程序通常不需要 CORSMiddleware
中间件。
原因:
同源策略: 跨域资源共享 (CORS) 是浏览器的一种安全机制,用于限制从一个源(协议、域名、端口)加载的网页去请求另一个源的资源。
Nginx 反向代理的作用: 当你使用 Nginx 作为反向代理时,Vue 前端和 FastAPI 后端都通过 Nginx 的同一个端口(例如 80)提供服务。从浏览器的角度来看,前端和后端是同源的,因为它们具有相同的协议(http 或 https)、相同的域名(或 IP 地址)和相同的端口。
-
请求流程:
- 客户端(浏览器)向 Nginx 发送请求(例如
http://XXXXXXXXXXX/api/users
)。 - Nginx 根据
location /api
的配置,将请求转发到 FastAPI 后端(http://127.0.0.1:8000/users
)。 - FastAPI 处理请求并返回响应给 Nginx。
- Nginx 将响应返回给客户端。
在这个过程中,浏览器只与 Nginx 交互,它认为所有请求都是发往同一个源的,因此不会触发 CORS 限制。
- 客户端(浏览器)向 Nginx 发送请求(例如
何时仍然需要 CORSMiddleware
:
尽管在大多数情况下不需要 CORSMiddleware
,但在以下情况下,你可能仍然需要它:
直接访问 FastAPI: 如果你允许客户端(例如其他应用程序或脚本)直接访问 FastAPI 的端口(例如
http://XXXXXXXXXXXXXX:8000
),而不是通过 Nginx,那么就需要CORSMiddleware
来处理跨域请求。子域名或不同端口: 如果你的 Vue 前端和 FastAPI 后端部署在不同的子域名(例如
frontend.example.com
和api.example.com
)或不同的端口上,即使它们都在同一台服务器上,浏览器仍然会认为它们是不同的源,需要CORSMiddleware
。复杂的 CORS 需求: 如果你有更复杂的 CORS 需求,例如需要精确控制允许的来源、方法、头部等,那么即使使用了 Nginx 反向代理,也可能需要使用
CORSMiddleware
来进行更细粒度的配置。
最佳实践:
- 优先使用 Nginx 反向代理解决跨域问题: 这是最简单、最有效的方法。
- 如果确实需要
CORSMiddleware
:-
在 FastAPI 中添加
CORSMiddleware
:from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = [ "http://localhost", # 允许本地访问 "http://XXXXXXXXXX", # 允许局域网访问 "http://XXXXXXXXXX", # 允许你的域名访问 # ... 其他允许的来源 ... ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], # 允许所有方法 (GET, POST, PUT, DELETE, etc.) allow_headers=["*"], # 允许所有头部 ) # ... 你的 API 路由 ...
allow_origins
: 指定允许访问的来源列表。你可以使用"*"
来允许所有来源(不推荐在生产环境中使用)。allow_credentials
: 如果你的 API 需要使用 cookies 或 HTTP 认证,设置为True
。allow_methods
: 指定允许的 HTTP 方法。allow_headers
: 指定允许的 HTTP 头部。
-
总结:
在 Nginx 反向代理的部署方式下,FastAPI 通常不需要 CORSMiddleware
,因为 Nginx 已经解决了跨域问题。只有在特殊情况下(例如直接访问 FastAPI、不同的子域名或端口、复杂的 CORS 需求)才需要使用 CORSMiddleware
。 优先通过 Nginx 解决跨域问题,保持后端代码的简洁。