FastAPI部署教程:Docker、Gunicorn与Nginx

FastAPI 部署教程:Docker、Gunicorn 与 Nginx

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,基于 Python 3.7+ 的标准类型提示。它以其高性能、易用性和强大的功能而闻名。本教程将指导您如何使用 Docker、Gunicorn 和 Nginx 部署 FastAPI 应用程序,实现可靠、可扩展和安全的生产环境。

为什么要使用 Docker、Gunicorn 和 Nginx?

  • Docker: 提供了一个轻量级、可移植的容器化解决方案,确保您的应用程序在不同环境中一致运行,简化了部署和管理过程。
  • Gunicorn: 作为 WSGI HTTP 服务器,充当 FastAPI 应用程序和 Nginx 之间的桥梁,处理并发请求并提高性能。
  • Nginx: 作为高性能的反向代理服务器,提供负载均衡、SSL 加密、静态文件服务等功能,增强安全性和可扩展性。

先决条件:

  • 已安装 Docker 和 Docker Compose
  • 基本的 Linux 命令行知识
  • 一个已编写完成的 FastAPI 应用程序

步骤 1: 创建 FastAPI 应用程序

如果您还没有 FastAPI 应用程序,可以创建一个简单的示例:

```python

main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
return {"Hello": "World"}

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
```

安装 FastAPI 和 Uvicorn (用于本地开发测试):

bash
pip install fastapi uvicorn

使用 Uvicorn 运行应用进行测试:

bash
uvicorn main:app --reload

步骤 2: 编写 Dockerfile

Dockerfile 包含构建 Docker 镜像的指令。在项目根目录下创建名为 Dockerfile 的文件,内容如下:

```dockerfile

使用官方 Python 运行时作为父镜像

FROM python:3.9

设置工作目录

WORKDIR /code

将当前目录内容复制到容器的 /code 目录中

COPY . /code/

安装依赖项

RUN pip install --no-cache-dir -r requirements.txt

安装 Gunicorn

RUN pip install gunicorn

使用 Gunicorn 运行应用

CMD ["gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:80"]
```

代码解释:

  • FROM python:3.9: 指定基础镜像为 Python 3.9。
  • WORKDIR /code: 设置容器内的工作目录为 /code
  • COPY . /code/: 将项目所有文件复制到容器的 /code 目录下。
  • RUN pip install --no-cache-dir -r requirements.txt: 安装 requirements.txt 文件中列出的所有依赖包。
  • RUN pip install gunicorn: 安装 Gunicorn。
  • CMD ["gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:80"]: 使用 Gunicorn 启动应用。
    • main:app: 指向您的 FastAPI 应用文件(main.py)和应用实例(app)。
    • -w 4: 指定 4 个 worker 进程。
    • -k uvicorn.workers.UvicornWorker: 使用 Uvicorn worker 类型,以获得异步支持。
    • -b 0.0.0.0:80: 绑定到 0.0.0.0:80,允许从容器外部访问。

别忘了创建 requirements.txt 文件,将 fastapiuvicorn 添加进去。

步骤 3: 编写 docker-compose.yml

Docker Compose 用于定义和运行多容器 Docker 应用程序。在项目根目录下创建名为 docker-compose.yml 的文件,内容如下:

```yaml
version: '3.8'

services:
web:
build: .
command: gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:80
volumes:
- .:/code
ports:
- "8000:80"
depends_on:
- db # 如果您的应用需要数据库,请添加相应的数据库服务
environment:
- DATABASE_URL=postgresql://user:password@db:5432/database_name
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- web
db: # 这是一个示例数据库服务配置,您可以根据需要进行修改
image: postgres:latest
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=database_name

volumes:
postgres_data:
```

代码解释:

  • version: '3.8': 指定 Docker Compose 文件版本。
  • services: 定义服务。
    • web: 您的 FastAPI 应用程序服务。
      • build: .: 使用当前目录下的 Dockerfile 构建镜像。
      • command: 覆盖 Dockerfile 中的 CMD 指令,再次使用 Gunicorn 启动应用。
      • volumes: 将项目目录挂载到容器的 /code 目录,方便开发时代码同步。
      • ports: 将容器的 80 端口映射到主机的 8000 端口,方便开发时测试,生产环境我们通常会让 nginx 直接映射到 80 端口。
      • depends_on: 指定依赖关系,确保 db 服务在 web 服务之前启动。
      • environment: 设置环境变量,例如数据库连接信息。
    • nginx: Nginx 服务。
      • image: nginx:latest: 使用最新的 Nginx 镜像。
      • ports: 将容器的 80 端口映射到主机的 80 端口。
      • volumes: 将本地的 Nginx 配置文件挂载到容器内的相应位置。
      • depends_on: 指定依赖关系,确保 web 服务在 nginx 服务之前启动。
    • db: 数据库服务配置(示例为 PostgreSQL,您可以根据需要进行修改)。
  • volumes: 定义数据卷。

步骤 4: 配置 Nginx

在项目根目录下创建 nginx 文件夹,并在其中创建 nginx.conf 文件,内容如下:

```nginx
user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
#tcp_nopush     on;

keepalive_timeout  65;

#gzip  on;

upstream app_server {
    server web:80;
}

server {
    listen 80;
    server_name  your_domain.com; # 将此处的 your_domain.com 改成你的域名或者服务器IP

    location / {
        proxy_pass http://app_server;
        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;
    }

    # 可选:配置静态文件服务
    # location /static {
    #     alias /code/static;
    # }
}

}
```

代码解释:

  • upstream app_server: 定义了一个名为 app_server 的上游服务器组,指向 web:80,即 FastAPI 应用服务。
  • server: 定义了一个服务器块。
    • listen 80: 监听 80 端口。
    • server_name your_domain.com: 设置您的域名或服务器 IP。
    • location /: 匹配所有请求。
      • proxy_pass http://app_server: 将请求转发到 app_server 上游服务器组。
      • proxy_set_header: 设置请求头,以便 FastAPI 应用获取客户端的真实 IP 等信息。
    • location /static: (可选)配置静态文件服务,将 /static 请求映射到容器内的 /code/static 目录。

步骤 5: 构建和运行

一切就绪后,使用以下命令构建和运行您的应用程序:

bash
docker-compose up --build

该命令会根据 docker-compose.yml 文件构建镜像并启动所有服务。

步骤 6: 访问您的应用程序

现在,您可以通过浏览器访问 http://localhost (开发测试环境) 或 http://your_domain.com (生产环境) 来访问您的 FastAPI 应用程序。如果是按照本文档配置,则需要通过 http://localhost:8000 来访问开发测试环境的应用。

进一步优化和安全加固:

  • 添加 HTTPS 支持: 使用 Let's Encrypt 等工具为您的 Nginx 服务器配置 SSL 证书,启用 HTTPS 加密。
  • 日志管理: 配置 Nginx 和 Gunicorn 的日志记录,并使用工具进行日志分析和监控。
  • 安全加固: 采取措施加固您的服务器和应用程序,例如限制 SSH 访问、更新软件包、配置防火墙等。
  • 负载均衡: 如果您的应用程序需要处理大量流量,可以使用 Nginx 的负载均衡功能将流量分发到多个 FastAPI 实例。
  • 使用独立的数据库服务: 对于生产环境,建议使用独立的数据库服务,而不是在 Docker Compose 中运行数据库。

总结

本教程详细介绍了如何使用 Docker、Gunicorn 和 Nginx 部署 FastAPI 应用程序。通过遵循这些步骤,您可以构建一个可靠、可扩展和安全的生产环境。请根据您的实际需求进行调整和优化,打造高性能的 API 服务。希望这篇文章对您有所帮助!

THE END