我正在使用
Nginx
和 Docker
以及 React frontend
和 Rails backend
API 设置 Web 应用程序,所有这些都在单个域上。我想直接从根 (example.com)
为前端提供服务,并在 API 请求以 /api
开头时将其路由到 Rails 后端。
这是我正在使用的设置:
对
example.com
的请求应该服务于 React 前端。
对 example.com/api/*
的请求应路由到 Rails API 后端。
结构如下:
/root/app/
├── docker-compose.yml
├── nginx.conf
├── backend/ # Rails API
│ ├── Dockerfile # Dockerfile
│ ├── config/routes.rb # Routes
└── frontend/ # React Web App
├── Dockerfile # Dockerfile
version: '3'
services:
# Rails Backend
rails_app:
build: ./backend
volumes:
- ./backend:/app
ports:
- "4000:4000"
environment:
RAILS_ENV: production
DATABASE_URL: postgres://your_username:your_password@db:5432/your_database_name
SECRET_KEY_BASE: xxxxxxxxxxxxxxxxxxxx
depends_on:
- db
# React Frontend
react_app:
build: ./frontend
volumes:
- ./frontend:/app
- /app/node_modules
ports:
- '3000:3000' #
environment:
- NODE_ENV=production
# PostgreSQL
db:
image: postgres:latest
ports:
- '5433:5432'
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: your_username
POSTGRES_PASSWORD: your_password
POSTGRES_DB: your_database_name
# Nginx
nginx:
image: nginx:latest
ports:
- '80:80'
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- rails_app
- react_app
volumes:
pgdata:
events {}
http {
server {
listen 80;
server_name example.com www.example.com;
# Rails App
location /api/ {
proxy_pass http://rails_app:4000;
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;
}
# React App
location / {
proxy_pass http://react_app: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;
}
}
}
Rails.application.routes.draw do
scope "/api" do
resources :posts # /api/posts
get "up", to: "rails/health#show", as: :rails_health_check # /api/up
end
end
当我访问
example.com
时,React 前端会按预期加载。
但是,当我尝试访问 example.com/api
时,我没有收到来自 Rails API 后端的任何响应。 Nginx 日志显示重复的 301 Moved Permanently
响应,导致重定向循环。
React 前端响应正常
ginx-1 | [07/11/2024:23:27:21 +0000]“GET /api/posts HTTP/1.1”301 0 ginx-1 | [07/11/2024:23:27:21 +0000]“获取/api/posts HTTP/1.1”301 0 ginx-1 | [07/11/2024:23:27:21 +0000]“获取/api/posts HTTP/1.1”301 0 ginx-1 | [07/11/2024:23:27:21 +0000]“GET /api/posts HTTP/1.1”301 0
如何正确配置 Nginx 和 Docker 以将
/api
下的 API 请求路由到我的 Rails 后端而不导致重定向循环?任何建议将不胜感激!
请在 proxy_pass URI 末尾添加尾部斜杠,如 http://rails_app:4000/
添加尾部斜杠告诉 NGINX 在将请求 URL 传递到后端服务之前去除 /api 前缀。这样,如果客户端请求 /api/posts,它将被代理到 http://rails_apps:4000/api