You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS EC2上React+Django+Docker-Compose用域名时出现Invalid Host Header错误

解决React应用"Invalid Host Header"生产环境安全方案

问题背景

在AWS EC2上部署React(前端)+Django(后端)Web应用,采用Docker-Compose容器化,Nginx反向代理将443端口流量转发至React的3000端口,以HTTPS提供服务。使用公网IP的HTTPS访问正常,但通过域名https://testportal.com访问时,出现Invalid Host Header错误。临时设置DANGEROUSLY_DISABLE_HOST_CHECK=true可解决问题,但该方案存在安全风险,不适用于生产环境。

相关配置信息

Docker Compose(docker-compose.yml)

version: "3"

services:
  react-app:
    build:
      context: ./frontend/webapp
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    stdin_open: true
    tty: true
    environment:
      - NODE_OPTIONS=--max-old-space-size=16384
      - NODE_OPTIONS=--openssl-legacy-provider
      - HOST=0.0.0.0
    networks:
      - mynetwork

  django-app:
    build:
      context: ./backend/webapp
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    command: python manage.py runserver 0.0.0.0:8000
    environment:
      - PYTHONDONTWRITEBYTECODE=1
      - PYTHONUNBUFFERED=1
    networks:
      - mynetwork

networks:
  mynetwork:
    driver: bridge

React Dockerfile

FROM node:21.7.3

ENV NODE_OPTIONS="--max-old-space-size=16384 --openssl-legacy-provider"

WORKDIR /app

COPY package.json ./

RUN npm install

COPY . .

RUN npm run build

EXPOSE 3000

CMD ["npm", "start"]

环境配置文件(.env)

HOST=testportal.com
HTTPS=true
PORT=3000

Nginx配置

server {
    listen 80;
    server_name www.testportal.com testportal.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name www.testportal.com testportal.com;

    ssl_certificate /etc/letsencrypt/live/testportal.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/testportal.com/privkey.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256";
    
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_stapling on;
    ssl_stapling_verify on;

    location / {
        proxy_pass http://localhost:3000;
        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;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_cache_bypass $http_upgrade;
    }

    error_page 404 /404.html;
    location = /404.html {
        internal;
    }
}

/etc/hosts文件

127.0.0.1 localhost
x.x.x.x testportal.com
x.x.x.x www.testportal.com

已尝试操作

  • 设置DANGEROUSLY_DISABLE_HOST_CHECK=true可临时解决问题,但存在安全风险
  • 验证域名已正确指向服务器公网IP
  • 确认域名解析正常,Nginx路由无明显异常,但React仍抛出主机头错误

目标

安全配置应用,使https://testportal.com的请求可正常处理,无需禁用主机检查。


解决方案

方案1:切换为生产环境运行React应用(推荐)

当前Dockerfile使用npm start运行React开发服务器,该服务器设计用于开发场景,存在性能瓶颈和安全限制(如Host头检查)。生产环境应直接运行build后的静态文件,推荐使用Nginx镜像托管:

修改React Dockerfile

FROM node:21.7.3 as builder

ENV NODE_OPTIONS="--max-old-space-size=16384 --openssl-legacy-provider"

WORKDIR /app

COPY package.json ./
RUN npm install

COPY . .
RUN npm run build

# 使用轻量级Nginx镜像运行静态文件
FROM nginx:alpine

# 复制build产物到Nginx静态目录
COPY --from=builder /app/build /usr/share/nginx/html

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

更新docker-compose.yml中的react-app配置

react-app:
    build:
      context: ./frontend/webapp
      dockerfile: Dockerfile
    ports:
      - "3000:80"  # 容器内端口改为Nginx默认的80
    networks:
      - mynetwork
    # 移除stdin_open、tty及不必要的环境变量

方案2:配置开发服务器允许指定主机(不推荐生产环境使用)

若因特殊需求需继续使用npm start运行开发服务器,可通过以下方式配置允许的主机:

方法A:通过环境变量指定

在React项目的.env文件中添加:

HOST=0.0.0.0
ALLOWED_HOSTS=testportal.com,www.testportal.com

或在docker-compose.yml的react-app服务中添加环境变量:

environment:
  - NODE_OPTIONS=--max-old-space-size=16384 --openssl-legacy-provider
  - HOST=0.0.0.0
  - ALLOWED_HOSTS=testportal.com,www.testportal.com

方法B:修改Webpack配置(需eject项目)

若项目已执行npm run eject,可编辑config/webpackDevServer.config.js中的allowedHosts:

allowedHosts: [
  'testportal.com',
  'www.testportal.com',
],

验证与重启

确认Nginx配置中的proxy_set_header Host $host;已正确设置(当前配置已包含),然后重启所有服务:

docker-compose down
docker-compose up --build -d

内容的提问来源于stack exchange,提问作者Vatsal Pathak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:24:52