Nginx配置SSL加速DockerFastAPI与React应用
亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《Nginx配置SSL证书,加速Docker FastAPI与React应用》很感兴趣。本篇文章就来给大家详细解析一下,主要介绍一下,希望所有认真读完的童鞋们,都有实质性的提高。

1. 理解SSL终止与Nginx反向代理
在生产环境中,直接在应用服务器(如FastAPI的Uvicorn)上配置SSL证书通常不是最佳实践。这会增加应用服务器的负担,并可能导致CORS等复杂问题。更推荐的做法是使用一个专门的反向代理服务器,如Nginx,来处理SSL加密与解密(即SSL终止)。客户端的HTTPS请求首先到达Nginx,Nginx解密后将HTTP请求转发给后端的应用服务,再将应用服务的HTTP响应加密后返回给客户端。这种架构有以下优势:
- 性能优化: Nginx针对高并发和静态文件服务进行了优化,处理SSL握手和加密/解密效率更高。
- 安全集中: 所有的SSL配置和证书管理都集中在Nginx,方便维护和更新。
- 简化应用: 后端应用无需关心SSL,只需监听HTTP端口,降低了应用开发的复杂性。
- 负载均衡与路由: Nginx可以轻松实现负载均衡和基于域名/路径的请求路由。
2. 项目结构与Docker Compose概览
假设您的项目包含一个FastAPI后端、一个React前端和一个PostgreSQL数据库,并通过Docker Compose进行容器化管理。初始的docker-compose.yml可能如下所示:
version: '3.7'
services:
frontend:
container_name: "frontend"
build:
context: ./frontend
stop_signal: SIGTERM
ports:
- "80:80" # 前端直接暴露80端口
volumes:
- ./uploads:/app/uploads
networks:
- good_network
depends_on:
- backend
backend:
container_name: "backend"
build:
context: ./backend
stop_signal: SIGTERM
ports:
- "8000:8000" # 后端直接暴露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:在此基础上,我们将引入Nginx服务。
3. 获取SSL证书
在配置Nginx之前,您需要获取SSL证书。通常,这可以通过Certbot工具与Let's Encrypt服务完成,它能提供免费的、受信任的证书。假设您的域名是mysite.ru,并且您希望后端通过子域名back.mysite.ru访问。
通过Certbot获取证书后,证书文件通常会存储在/etc/letsencrypt/live/
- fullchain.pem:包含主证书和所有中间证书。
- privkey.pem:证书的私钥。
- chain.pem:仅包含中间证书(有时也包含在fullchain.pem中)。
这些文件需要在Nginx容器中可访问。
4. Nginx配置 (nginx.conf)
创建一个nginx.conf文件,用于定义Nginx如何处理传入的HTTP和HTTPS请求,并将其代理到内部的FastAPI和React服务。
# 定义Nginx工作进程可以同时处理的最大连接数
events {
worker_connections 1024;
}
http {
# 定义后端服务的上游(upstream)
# 'back' 是内部服务名称,对应docker-compose中的backend服务
# 'back.mysite.ru:8000' 是后端服务在Docker网络中的地址和端口
upstream back {
server back.mysite.ru:8000;
}
# 定义前端服务的上游(upstream)
# 'front' 是内部服务名称,对应docker-compose中的frontend服务
# 'mysite.ru:80' 是前端服务在Docker网络中的地址和端口
upstream front {
server mysite.ru:80;
}
# Nginx服务器块:处理后端服务的HTTP请求(back.mysite.ru:80)
server {
listen 80;
server_name back.mysite.ru; # 监听子域名
location / {
# 将请求代理到名为'back'的上游服务
proxy_pass http://back;
# 设置Host头,确保后端服务能正确识别请求来源
proxy_set_header Host $host;
# 传递客户端的真实IP地址
proxy_set_header X-Real-IP $remote_addr;
# 传递代理链中的所有IP地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 告知后端服务,原始请求是通过HTTP协议到达Nginx的
proxy_set_header X-Forwarded-Proto http;
}
}
# Nginx服务器块:处理后端服务的HTTPS请求(back.mysite.ru:443)
server {
listen 443 ssl; # 监听443端口并启用SSL
server_name back.mysite.ru;
# SSL证书路径,这些路径将通过Docker卷挂载到容器内部
ssl_certificate /etc/letsencrypt/live/back.mysite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/back.mysite.ru/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/back.mysite.ru/chain.pem; # 可选,用于信任链
location / {
proxy_pass http://back; # 代理到内部的HTTP后端服务
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 告知后端服务,原始请求是通过HTTPS协议到达Nginx的
proxy_set_header X-Forwarded-Proto https;
}
}
# Nginx服务器块:处理前端服务的HTTP请求(mysite.ru:80)
server {
listen 80;
server_name mysite.ru;
location / {
proxy_pass http://front;
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 http;
}
}
# Nginx服务器块:处理前端服务的HTTPS请求(mysite.ru:443)
server {
listen 443 ssl;
server_name mysite.ru;
ssl_certificate /etc/letsencrypt/live/mysite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.ru/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/mysite.ru/chain.pem;
location / {
proxy_pass http://front;
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 https;
}
}
}注意事项:
- upstream块中的server地址应是Docker内部网络中服务可访问的名称和端口(例如,back.mysite.ru:8000或直接使用服务名backend:8000,具体取决于您的DNS解析和网络配置)。这里假设您在Docker Compose中为服务定义了别名或使用了内部DNS解析。在标准Docker Compose网络中,服务名即为主机名,所以backend:8000和frontend:80通常可以直接使用。
- ssl_certificate、ssl_certificate_key和ssl_trusted_certificate路径必须指向Nginx容器内部可以访问的证书文件。
5. Nginx Dockerfile
创建一个简单的Nginx Dockerfile,将自定义的nginx.conf复制到容器中:
FROM nginx:latest # 使用官方Nginx镜像 # 将自定义的nginx.conf复制到Nginx的配置目录 COPY nginx.conf /etc/nginx/nginx.conf
将此文件保存为nginx/Dockerfile(假设您在项目根目录下创建了一个nginx子目录)。
6. 更新Docker Compose配置
现在,将Nginx服务集成到docker-compose.yml中:
version: '3.7'
services:
frontend:
container_name: "frontend"
build:
context: ./frontend
stop_signal: SIGTERM
# 不再直接暴露80端口到主机,由Nginx处理
# ports:
# - "80:80"
volumes:
- ./uploads:/app/uploads
networks:
- good_network
depends_on:
- backend
backend:
container_name: "backend"
build:
context: ./backend
stop_signal: SIGTERM
# 不再直接暴露8000端口到主机,由Nginx处理
# ports:
# - "8000: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
# 新增Nginx服务
nginx:
build: ./nginx # 指向Nginx Dockerfile所在的目录
ports:
- "80:80" # 暴露HTTP端口,用于重定向或Certbot验证
- "443:443" # 暴露HTTPS端口
volumes:
# 挂载宿主机的Certbot证书目录到Nginx容器
# 确保宿主机上的 /etc/letsencrypt 目录存在且包含有效证书
- /etc/letsencrypt:/etc/letsencrypt:ro # 只读模式挂载
networks:
- good_network
depends_on:
- frontend # 确保前端服务启动后再启动Nginx
- backend # 确保后端服务启动后再启动Nginx
networks:
good_network:
volumes:
postgres_data:关键更改:
- 移除frontend和backend服务的ports映射: 它们现在只在内部网络中通过Nginx访问。
- 新增nginx服务:
- build: ./nginx:告诉Docker Compose在./nginx目录下构建Nginx镜像。
- ports: - "80:80" - "443:443":将Nginx容器的80和443端口映射到宿主机的80和443端口,以便外部流量访问。
- volumes: - /etc/letsencrypt:/etc/letsencrypt:ro:这是最关键的一步。它将宿主机上Certbot生成的证书目录挂载到Nginx容器的相同路径,并以只读(ro)模式挂载,确保Nginx可以读取证书文件。在运行此配置之前,请确保您的宿主机上已经通过Certbot或其他方式获取了证书,并位于/etc/letsencrypt目录下。
- depends_on: - frontend - backend:确保Nginx在前端和后端服务启动后才启动。
7. 部署与验证
- 获取证书: 在宿主机上运行Certbot命令获取或更新您的域名(mysite.ru和back.mysite.ru)的SSL证书。例如:
sudo certbot certonly --nginx -d mysite.ru -d back.mysite.ru # 或者如果Nginx不在宿主机上,使用webroot模式 # sudo certbot certonly --webroot -w /var/www/html -d mysite.ru -d back.mysite.ru
确保证书文件已正确生成并放置在/etc/letsencrypt/live/目录下。
- 启动服务: 在项目根目录下运行:
docker-compose up --build -d
- 验证:
- 通过浏览器访问 https://mysite.ru 和 https://back.mysite.ru。检查是否显示安全连接(绿色锁图标)。
- 您也可以使用curl命令验证:
curl -v https://mysite.ru curl -v https://back.mysite.ru/your_api_endpoint
检查输出中是否有SSL/TLS握手信息。
8. 总结与最佳实践
通过Nginx作为反向代理进行SSL终止,您已经成功地为Docker容器化的FastAPI和React应用配置了HTTPS。这种方法不仅解决了直接在应用层处理SSL的复杂性,还提供了更灵活、更安全的部署方案。
其他注意事项和最佳实践:
- HTTP到HTTPS重定向: 为了强制所有流量都使用HTTPS,您可以在Nginx的HTTP服务器块中添加重定向规则:
server { listen 80; server_name mysite.ru back.mysite.ru; return 301 https://$host$request_uri; # 将所有HTTP请求重定向到HTTPS } - CORS处理: 当Nginx作为反向代理时,FastAPI应用仍然会收到来自Nginx的HTTP请求。如果您的FastAPI应用需要处理CORS,请确保在FastAPI应用中正确配置CORS中间件,允许来自您前端域名的请求。例如,如果您的前端在mysite.ru,后端在back.mysite.ru,则FastAPI的CORS配置应允许https://mysite.ru作为源。Nginx通过X-Forwarded-Proto: https头告知后端原始请求是HTTPS,后端可以据此进行逻辑判断。
- 证书自动续期: 对于Let's Encrypt证书,务必设置Certbot的自动续期机制(通常Certbot安装后会自动配置一个cron job或systemd timer)。
- Nginx安全强化: 考虑在Nginx配置中添加额外的安全措施,如:
- add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; (HSTS)
- 配置更强的SSL/TLS协议和密码套件,禁用旧版本和弱加密算法。
- 限制请求体大小,防止DDoS攻击。
- 日志管理: 配置Nginx的访问日志和错误日志,以便于监控和故障排查。
通过遵循这些步骤和最佳实践,您可以构建一个安全、高效且易于维护的Docker容器化应用部署环境。
到这里,我们也就讲完了《Nginx配置SSL加速DockerFastAPI与React应用》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!
Golang代理模式实现:接口封装控制访问
- 上一篇
- Golang代理模式实现:接口封装控制访问
- 下一篇
- ChatGPT对话导出与数据保存方法
-
- 文章 · python教程 | 3分钟前 | 身份验证 断点续传 requests库 PythonAPI下载 urllib库
- Python调用API下载文件方法
- 227浏览 收藏
-
- 文章 · python教程 | 5分钟前 |
- Windows7安装RtMidi失败解决办法
- 400浏览 收藏
-
- 文章 · python教程 | 11分钟前 |
- Python异步任务优化技巧分享
- 327浏览 收藏
-
- 文章 · python教程 | 20分钟前 |
- PyCharm图形界面显示问题解决方法
- 124浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python自定义异常类怎么创建
- 450浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python抓取赛狗数据:指定日期赛道API教程
- 347浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python3中datetime常用转换方式有哪些?
- 464浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- PyCharm无解释器问题解决方法
- 290浏览 收藏
-
- 文章 · python教程 | 2小时前 | 性能优化 Python正则表达式 re模块 匹配结果 正则模式
- Python正则表达式入门与使用技巧
- 112浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- MacPython兼容LibreSSL的解决方法
- 324浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- OdooQWeb浮点转整数技巧
- 429浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- VSCodePython开发全流程详解
- 348浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3178次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3389次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3418次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4523次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3797次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览

