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

配置Nginx与Docker实现React+Rails路由,解决/api重定向循环问题

解决Nginx+Docker下React前端与Rails API的/api路由重定向循环问题

核心问题分析

重定向循环通常由两个原因导致:

  1. Rails路由未正确匹配/api前缀,返回301重定向到带斜杠的路径,Nginx再次转发后重复触发
  2. Nginx的proxy_pass配置错误,导致路径转发异常,触发Rails的路由重定向

步骤1:修正Rails路由配置

确保Rails明确处理/api前缀的请求,且关闭不必要的尾斜杠重定向:

  1. 在config/routes.rb中,用scope或namespace定义/api路由,并禁用尾斜杠重定向:
Rails.application.routes.draw do
  # 禁用尾斜杠重定向,避免Rails自动返回301
  scope '/api', trailing_slash: false do
    # 示例API路由
    resources :users, only: [:index, :show]
    get '/health', to: 'health#check'
  end
end
  1. 若全局需要关闭尾斜杠重定向,可在config/application.rb中添加:
config.action_controller.default_url_options = { trailing_slash: false }

步骤2:修复Nginx配置

关键是保证proxy_pass的路径转发正确,同时传递必要的请求头给Rails:
以下是完整的nginx.conf示例:

server {
    listen 80;
    server_name example.com;

    # 处理/api开头的请求,转发到Rails容器
    location /api {
        # 注意:proxy_pass结尾不要加斜杠,否则Nginx会截断/api前缀
        proxy_pass http://rails:3000;
        # 传递真实请求的Host头,避免Rails生成错误的URL
        proxy_set_header Host $host;
        # 传递客户端IP
        proxy_set_header X-Forwarded-For $remote_addr;
        # 传递请求协议(若使用HTTPS,需修改为$scheme或直接写https)
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 处理React前端请求,支持React Router的单页路由
    location / {
        root /usr/share/nginx/html;
        # 优先匹配静态文件,匹配不到则返回index.html(React路由接管)
        try_files $uri $uri/ /index.html;
    }
}

Nginx配置的关键注意点:

  • 禁止在proxy_pass结尾加斜杠:如果写成http://rails:3000/,Nginx会把/api/users转发为/users,Rails匹配不到会返回301重定向到/api/users/,触发循环。
  • 传递正确的请求头:如果Rails开启了force_ssl,必须设置X-Forwarded-Proto为https,否则Rails会强制重定向到HTTPS,导致循环。

步骤3:Docker Compose配置验证

确保所有服务在同一网络下,容器名称与Nginx配置中的地址一致:

version: '3.8'
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      # 若使用HTTPS,添加443端口映射
      # - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      # 挂载React构建后的静态文件目录
      - ./react/build:/usr/share/nginx/html
    depends_on:
      - react
      - rails
    networks:
      - app-network

  react:
    build: ./react
    # React项目的Dockerfile需完成构建,输出到build目录
    # 示例Dockerfile:
    # FROM node:18-alpine
    # WORKDIR /app
    # COPY package*.json ./
    # RUN npm install
    # COPY . .
    # RUN npm run build
    # CMD ["cp", "-r", "build/*", "/usr/share/nginx/html/"]
    networks:
      - app-network

  rails:
    build: ./rails
    environment:
      - RAILS_ENV=production
      - DATABASE_URL=postgres://user:password@db:5432/app_db
    # Rails服务器需监听0.0.0.0,否则容器外无法访问
    # 示例puma.rb配置:bind 'tcp://0.0.0.0:3000'
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

最后排查事项

  1. 清除浏览器缓存:301是永久重定向,浏览器会缓存旧的重定向规则,修改配置后用隐私窗口测试。
  2. 检查Rails日志:查看Rails容器的日志,确认请求是否正确到达,以及重定向的原因。
  3. HTTPS场景适配:若使用HTTPS,需在Nginx中配置SSL证书,并将X-Forwarded-Proto设置为https,同时确保Rails的config.force_ssl = true(或根据需求配置)。

内容的提问来源于stack exchange,提问作者Hamdi Huntürk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 13:01:12