如何为FastAPI应用配置SSL证书?含Docker前后端部署场景
配置SSL证书解决方案
方案一:用Nginx反向代理统一处理SSL(推荐)
这种方式无需修改前端和后端代码,由Nginx统一接管HTTPS流量,同时能彻底解决CORS问题。
步骤1:修改docker-compose.yml,添加Nginx服务
调整原有服务的端口映射,让Nginx成为对外唯一入口:
version: '3.7' services: nginx: container_name: "nginx" image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot networks: - good_network depends_on: - frontend - backend frontend: container_name: "frontend" build: context: ./frontend stop_signal: SIGTERM # 仅在内部网络暴露端口,不再直接对外映射 expose: - "80" volumes: - ./uploads:/app/uploads networks: - good_network depends_on: - backend backend: container_name: "backend" build: context: ./backend stop_signal: SIGTERM # 仅在内部网络暴露端口,不再直接对外映射 expose: - "8000" networks: - good_network volumes: - ./uploads:/app/uploads depends_on: - postgres postgres: container_name: "postgres" image: postgres:16.0 healthcheck: test: [ "CMD-SHELL", "pg_isready -d sugar -U postgres" ] interval: 5s timeout: 5s retries: 5 start_period: 5s restart: unless-stopped ports: - "5432:5432" volumes: - ./postgres_data:/var/lib/postgresql/data networks: - good_network networks: good_network: volumes: postgres_data:
步骤2:创建Nginx配置文件
在./nginx/conf.d/default.conf中添加以下配置(替换your-domain.com为你的实际域名):
server { listen 80; server_name your-domain.com; # 处理Certbot域名验证请求 location /.well-known/acme-challenge/ { root /var/www/certbot; } # 所有HTTP请求强制重定向到HTTPS location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name your-domain.com; # 配置SSL证书路径 ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # 转发前端页面请求 location / { proxy_pass http://frontend:80; 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; } # 转发后端API请求(假设前端API前缀为/api) location /api { proxy_pass http://backend: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; } }
步骤3:挂载Certbot证书
将已生成的Certbot证书目录挂载到Nginx容器的/etc/letsencrypt路径,确保路径与配置文件一致。
步骤4:简化CORS配置
由于前端和后端都通过同一HTTPS域名访问,同源策略下不会触发CORS限制。若FastAPI仍需配置CORS,只需允许当前域名:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["https://your-domain.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
方案二:直接给FastAPI和前端配置SSL(不推荐)
若不想使用Nginx,可分别为前后端配置SSL,但需处理证书挂载和CORS问题。
后端调整
- 在docker-compose的backend服务中添加证书挂载:
volumes: - ./uploads:/app/uploads - ./certbot/live/your-domain.com/fullchain.pem:/app/fullchain.pem - ./certbot/live/your-domain.com/privkey.pem:/app/privkey.pem
- 修正uvicorn启动命令的证书路径:
uvicorn.run( "main:app", host="0.0.0.0", port=8000, ssl_keyfile="./privkey.pem", ssl_certfile="./fullchain.pem" )
- 配置CORS允许前端HTTPS域名:
app.add_middleware( CORSMiddleware, allow_origins=["https://your-domain.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
前端调整
- 修改前端Dockerfile,用Nginx配置SSL并挂载证书文件,确保前端以HTTPS方式运行。
- 将前端API请求地址改为后端HTTPS地址(如
https://your-domain.com:8000)。
关键注意事项
- 确保域名已解析到服务器公网IP,Certbot生成证书需要域名可正常访问。
- 避免同时暴露HTTP和HTTPS端口,防止出现混合内容错误。
- 证书到期后,执行
certbot renew命令更新,Nginx会自动加载新证书。
内容的提问来源于stack exchange,提问作者TASK
相关产品推荐
相关产品推荐

