如何同时配置并连接Django/Python与React服务至AWS Elastic Beanstalk
我刚帮团队完成了Django+React到AWS Elastic Beanstalk的部署,踩了不少坑,分享下亲测有效的实操步骤:
一般有两种主流方案:
- 单环境部署:把React构建后的静态文件集成到Django项目中,一起部署到同一个EB Python环境,适合中小型项目,运维简单。
- 多环境分离:Django作为API服务部署到EB Python环境,React作为前端部署到EB Node.js环境,前后端完全独立,适合大型项目或需要单独扩容的场景。
先讲最常用的单环境方案,最后补充分离部署的要点。
先把你的项目整理成这个结构,EB会自动识别关键文件:
my-project/ ├── .ebextensions/ # EB专属配置文件夹,必须有! │ ├── django.config │ └── nginx.config ├── backend/ # Django项目根目录(把你的Django代码放这里) │ ├── my_django_app/ # 你的Django主应用 │ ├── manage.py │ └── requirements.txt ├── frontend/ # React项目根目录(create-react-app生成的代码放这里) │ ├── src/ │ ├── package.json │ └── build/ # React构建后的产物(执行npm run build生成) └── .gitignore # 记得忽略venv、node_modules、build这些文件夹
1. 核心设置(settings.py)
打开backend/my_django_app/settings.py,做以下调整:
import os from pathlib import Path # 修正BASE_DIR指向项目根目录(my-project) BASE_DIR = Path(__file__).resolve().parent.parent.parent # 生产环境必须关闭DEBUG DEBUG = False # 允许EB的域名访问,生产环境建议写具体域名,测试阶段可以用['*'] ALLOWED_HOSTS = ['your-eb-environment-name.elasticbeanstalk.com', '*'] # 静态文件配置:把React构建的静态文件也纳入Django的静态资源管理 STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # collectstatic会把所有静态文件放到这里 STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'frontend/build/static'), # 指向React构建后的静态文件夹 ] # 模板配置:让Django能找到React的index.html TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'frontend/build')], # 指向React构建后的根目录 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] # 数据库配置(EB默认会创建RDS,或者你可以自己配置) # 如果用EB的RDS,记得在EB控制台配置环境变量,然后用os.getenv获取 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.getenv('DB_NAME'), 'USER': os.getenv('DB_USER'), 'PASSWORD': os.getenv('DB_PASSWORD'), 'HOST': os.getenv('DB_HOST'), 'PORT': os.getenv('DB_PORT'), } }
2. 路由配置(urls.py)
修改backend/my_django_app/urls.py,让所有非API的请求都指向React的index.html(解决单页应用路由问题):
from django.contrib import admin from django.urls import path, include from django.views.generic import TemplateView urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('your_api_app.urls')), # 你的API路由 # 所有前端路由都转发到React的index.html path('', TemplateView.as_view(template_name='index.html')), ]
3. 生成依赖清单
在backend目录下执行:
pip freeze > requirements.txt
确保所有Django依赖都被记录,比如django、psycopg2-binary(如果用PostgreSQL)、django-cors-headers(如果需要跨域)等。
1. 构建路径与API代理
- 开发阶段:在
frontend/package.json中添加代理,方便本地调试:
这样React里调用"proxy": "http://localhost:8000"/api/xxx会自动转发到Django的本地服务。 - 生产阶段:直接用相对路径
/api/xxx调用接口(因为部署在同一个域名下),或者配置EB的域名作为API地址。
2. 预构建React
在frontend目录下执行:
npm install npm run build
确保frontend/build文件夹生成,里面包含index.html和static文件夹。
这部分是部署的关键,告诉EB怎么处理Python环境、静态文件和Nginx路由。
1. django.config(Python环境配置)
创建.ebextensions/django.config:
option_settings: # 指定WSGI路径,替换成你的Django项目的WSGI文件路径 aws:elasticbeanstalk:container:python: WSGIPath: backend/my_django_app/wsgi.py # 静态文件映射:把/static/路径指向staticfiles文件夹 aws:elasticbeanstalk:environment:proxy:staticfiles: /static/: staticfiles container_commands: # 执行数据库迁移(只在主节点执行) 01_migrate: command: "source /var/app/venv/staging-LQM1lest/bin/activate && python backend/manage.py migrate" leader_only: true # 收集静态文件到STATIC_ROOT 02_collectstatic: command: "source /var/app/venv/staging-LQM1lest/bin/activate && python backend/manage.py collectstatic --noinput"
⚠️ 注意:虚拟环境路径/var/app/venv/staging-LQM1lest/bin/activate可能会变,如果部署时出错,可以登录EC2实例查看实际路径,或者简化成python backend/manage.py migrate(EB会自动激活虚拟环境)。
2. nginx.config(解决React路由刷新404问题)
创建.ebextensions/nginx.config:
files: "/etc/nginx/conf.d/00_app.conf": mode: "000644" owner: root group: root content: | server { listen 80; server_name localhost; # 处理前端路由:所有请求先找静态文件,找不到就返回index.html location / { root /var/app/current/frontend/build; try_files $uri $uri/ /index.html; } # 静态文件直接返回 location /static/ { alias /var/app/current/staticfiles/; } # API请求转发到Django的WSGI服务 location /api/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
这个配置会覆盖EB默认的Nginx设置,确保React单页应用的路由刷新正常。
1. 安装EB CLI
先安装AWS EB命令行工具:
pip install awsebcli
然后配置AWS凭证:aws configure,输入你的Access Key和Secret Key。
2. 初始化EB项目
在项目根目录执行:
eb init
按照提示选择:
- AWS区域(比如us-east-1)
- 创建新应用或选择已有应用
- 选择Python平台(注意选和你的Django兼容的Python版本,比如Python 3.9)
3. 创建EB环境
eb create my-django-react-env
等待环境创建完成,这个过程会自动创建EC2、RDS(如果配置了)、负载均衡等资源。
4. 部署代码
eb deploy
部署完成后,访问EB环境的域名,就能看到React应用,并且能正常调用Django API了。
如果需要前后端独立部署:
- Django API部署:
- 配置
django-cors-headers,允许React环境的域名跨域访问 - 部署到EB Python环境,只提供API服务
- 配置
- React前端部署:
- 把React项目部署到EB Node.js环境,EB会自动执行
npm install和npm run build - React的API地址配置成Django EB环境的域名
- 把React项目部署到EB Node.js环境,EB会自动执行
- 这种方案的好处是可以单独扩容前后端,适合流量较大的项目。
- 静态文件加载失败:查看EB日志(
eb logs),确认collectstatic命令是否执行成功,静态文件路径是否正确。 - React路由刷新404:检查Nginx配置中的
try_files规则是否生效,确保所有非API请求都转发到index.html。 - 数据库迁移失败:查看日志,确认数据库环境变量是否配置正确,RDS实例是否允许EB环境的安全组访问。
- 环境变量配置:在EB控制台的"配置"->"软件"中添加环境变量(比如SECRET_KEY、数据库信息),Django中用
os.getenv()获取。
内容的提问来源于stack exchange,提问作者Kwanghwi Kim

