Vue + FastAPI 怎样在生产环境部署

如果是在开发环境中的运行方法:

在一个终端中 , 启动后端

fastapi run api/main.py

打开另一个终端,启动前端:
npm run dev

项目打包生产环境正式部署方法:

要将 Vue 前端和 FastAPI 后端部署在同一台电脑上,并充分利用多 CPU 且避免跨域问题,最简便的方法是使用 反向代理 和 进程管理器。以下是详细步骤和解释:

  1. 项目准备:
  • Vue 前端:

    • 确保你的 Vue 项目已经构建(npm run build),生成 dist 目录(或其他配置的输出目录)。
    • Vue 项目中与后端 API 交互时,使用相对路径(例如 /api/users)或环境变量配置的基础 URL。不要硬编码后端地址和端口。
  • FastAPI 后端:

    • 确保你的 FastAPI 应用可以正常运行。
    • FastAPI 应用监听一个端口(例如 8000)。
  1. 安装和配置 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
    • 修改配置文件 (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
      • 如果没有错误,继续下一步。
    • 启动/重启 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 (重启)
  1. 使用 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 环境):

      1. 全局安装 pm2: npm install -g pm2
      2. 启动 FastAPI:
        pm2 start "gunicorn your_app_module:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000" --name fastapi-app
        
      3. 保存当前进程列表: pm2 save
      4. 设置开机自启: pm2 startup (按照提示操作)
    • 使用 Supervisor (Python 环境):

      1. 安装 Supervisor: pip install supervisor

      2. 创建 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
        
      3. 启动 Supervisor: supervisord -c supervisord.conf

      4. 使用 supervisorctl 管理进程 (例如 supervisorctl status, supervisorctl restart fastapi-app)。 配置开机自启通常需要将 supervisord 添加到系统服务。

  1. 访问你的应用:

现在,你应该可以通过浏览器访问 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 请求的写法。

  1. 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.3localhost 只在服务器本机访问时有效,而 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 地址访问。

  1. 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。

  • 环境变量 (更灵活):

    1. 在 Vue 项目的根目录下创建 .env 文件 (或 .env.development, .env.production 等,根据你的环境)。

    2. .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 基础路径不同,可以修改
      
    3. 在 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,而无需修改代码。

  1. FastAPI 代码 (无需修改):

FastAPI 代码中不需要做任何修改。它只需要监听本地的 8000 端口 (或其他你配置的端口),并通过 Uvicorn/Gunicorn 启动即可。

  1. 客户端访问:

其他电脑上的用户,只需要在浏览器中输入服务器地址就可以访问你的 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 地址)和相同的端口。

  • 请求流程:

    1. 客户端(浏览器)向 Nginx 发送请求(例如 http://XXXXXXXXXXX/api/users)。
    2. Nginx 根据 location /api 的配置,将请求转发到 FastAPI 后端(http://127.0.0.1:8000/users)。
    3. FastAPI 处理请求并返回响应给 Nginx。
    4. Nginx 将响应返回给客户端。

    在这个过程中,浏览器只与 Nginx 交互,它认为所有请求都是发往同一个源的,因此不会触发 CORS 限制。

何时仍然需要 CORSMiddleware

尽管在大多数情况下不需要 CORSMiddleware,但在以下情况下,你可能仍然需要它:

  1. 直接访问 FastAPI: 如果你允许客户端(例如其他应用程序或脚本)直接访问 FastAPI 的端口(例如 http://XXXXXXXXXXXXXX:8000),而不是通过 Nginx,那么就需要 CORSMiddleware 来处理跨域请求。

  2. 子域名或不同端口: 如果你的 Vue 前端和 FastAPI 后端部署在不同的子域名(例如 frontend.example.comapi.example.com)或不同的端口上,即使它们都在同一台服务器上,浏览器仍然会认为它们是不同的源,需要 CORSMiddleware

  3. 复杂的 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 解决跨域问题,保持后端代码的简洁。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容