从零到部署:用Uvicorn和Docker打包你的FastAPI应用(附Nginx配置)
从零到部署:用Uvicorn和Docker打包你的FastAPI应用(附Nginx配置)
在当今快速迭代的Web开发领域,FastAPI凭借其卓越的性能和直观的异步支持,已成为Python开发者构建API服务的首选框架。而将本地开发的原型转化为可投入生产的稳定服务,则需要一套完整的部署工具链。本文将带你从零开始,构建一个包含Uvicorn服务器、Docker容器化和Nginx反向代理的完整部署方案。
1. 开发环境搭建与Uvicorn基础配置
在开始部署之前,我们需要确保开发环境配置正确。FastAPI与Uvicorn的组合为开发者提供了极佳的本地调试体验。
首先创建并激活虚拟环境:
python -m venv venv source venv/bin/activate # Linux/macOS venv\Scripts\activate # Windows安装必要的依赖包:
pip install fastapi uvicorn一个典型的FastAPI应用结构如下:
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"} @app.get("/items/{item_id}") async def read_item(item_id: int): return {"item_id": item_id}使用Uvicorn运行开发服务器时,推荐以下参数组合:
uvicorn main:app --host 0.0.0.0 --port 8000 --reload提示:
--reload参数会在代码变更时自动重启服务,非常适合开发阶段使用,但切勿在生产环境中启用。
2. 构建生产级Docker镜像
当应用开发完成后,我们需要将其打包为Docker镜像以便部署。以下是经过优化的Dockerfile配置:
# 使用官方Python精简镜像作为基础 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 先安装依赖,利用Docker缓存层 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 设置环境变量 ENV PYTHONPATH=/app ENV PORT=8000 # 暴露端口 EXPOSE $PORT # 运行命令 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]构建镜像时,我们可以使用多阶段构建来进一步优化镜像大小:
# 第一阶段:构建环境 FROM python:3.9 as builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt # 第二阶段:运行环境 FROM python:3.9-slim WORKDIR /app # 从构建阶段复制已安装的包 COPY --from=builder /root/.local /root/.local COPY . . # 确保脚本可执行 ENV PATH=/root/.local/bin:$PATH ENV PYTHONPATH=/app EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]构建并运行镜像:
docker build -t fastapi-app . docker run -d -p 8000:8000 --name myapp fastapi-app3. 使用Docker Compose编排服务
实际生产环境中,我们的应用通常需要与其他服务(如数据库)协同工作。Docker Compose可以完美解决这个问题。
version: '3.8' services: web: build: . ports: - "8000:8000" environment: - DATABASE_URL=postgres://user:password@db:5432/mydb depends_on: - db restart: unless-stopped db: image: postgres:13 environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" volumes: postgres_data:关键配置说明:
- restart策略:设置为
unless-stopped确保服务异常退出后自动重启 - 环境变量:通过环境变量配置数据库连接,避免硬编码
- 数据持久化:使用volume保存PostgreSQL数据,防止容器重启后数据丢失
启动整个服务栈:
docker-compose up -d4. 生产环境优化与Nginx配置
直接暴露Uvicorn服务到公网并不是最佳实践。我们应该使用Nginx作为反向代理,它能够提供:
- 静态文件服务
- SSL终止
- 请求缓冲
- 负载均衡
基础Nginx配置示例:
server { listen 80; server_name yourdomain.com; location / { proxy_pass http://web: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; } location /static/ { alias /app/static/; } }对于生产环境,我们还需要配置SSL证书。使用Let's Encrypt可以免费获取可信证书:
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d yourdomain.comNginx与Uvicorn的完整Docker Compose配置:
version: '3.8' services: web: build: . expose: - "8000" environment: - DATABASE_URL=postgres://user:password@db:5432/mydb depends_on: - db restart: unless-stopped nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot depends_on: - web restart: unless-stopped db: image: postgres:13 environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb volumes: - postgres_data:/var/lib/postgresql/data volumes: postgres_data:5. 性能调优与监控
在生产环境中运行FastAPI应用时,我们需要关注几个关键性能指标:
Uvicorn工作进程配置建议:
| 服务器配置 | 推荐worker数 | 说明 |
|---|---|---|
| 1核CPU | 1-2 | 避免上下文切换开销 |
| 2核CPU | 3-4 | 充分利用CPU资源 |
| 4核CPU+ | CPU核数+1 | 通用公式 |
启动命令示例:
uvicorn main:app --workers 4 --host 0.0.0.0 --port 8000监控方案:
- 内置日志:Uvicorn提供详细的访问日志和错误日志
- Prometheus监控:集成
prometheus-fastapi-instrumentatorfrom prometheus_fastapi_instrumentator import Instrumentator Instrumentator().instrument(app).expose(app) - 健康检查端点:
@app.get("/health") async def health_check(): return {"status": "healthy"}
性能优化技巧:
使用
httptools和uvloop提升Uvicorn性能:pip install httptools uvloop启动命令:
uvicorn main:app --loop uvloop --http httptools对于CPU密集型任务,考虑使用
asyncpg替代同步的PostgreSQL驱动合理配置Keep-Alive:
keepalive_timeout 65; keepalive_requests 100;
在实际部署中,我们发现使用Docker的--memory限制参数可以有效防止内存泄漏导致的问题:
docker run -d --memory="512m" --name myapp fastapi-app