Rails 4 server/VueJS 开发服务器和子域的 Nginx 反向代理
Nginx reverse proxies for Rails 4 server/VueJS dev server and subdomains
我使用带有老化前端的整体式 Rails 4 应用程序。我的主要目标:在 VueJS 中构建一个新的独立前端,并将 Rails 服务器保持为 API,nginx 弥合了它们之间的差距。
在我的开发环境中设置原型一直是一个挑战。这就是我的立场:
- 当前应用使用通配符子域,因此我需要能够处理
XYZ.localhost
个 URL,无论 XYZ 是什么。
- Webpack 开发服务器位于
http://localhost:8080
。我打算默认将代理调用反向到此服务器。
- 遗留 Rails 开发服务器存在于
http://localhost:3000
。我打算在这里反转以 /api/
开头的代理调用。它在大多数请求中都需要一个子域,因此 http://clumsypanda.localhost/api/candy
应该代理到 http://clumsypanda.localhost:3000/candy
.
我想我已经记下了前两个:当我访问 http://XYZ.localhost
时,nginx 为我提供 VueJS 内容。不过,我在调用 http://XYZ.localhost/api/whatever
时只收到 502 错误。具体来说,nginx 报告:
XYZ.localhost could not be resolved (3: Host not found), client: ::1,
server: localhost, request: "POST /api/login HTTP/1.1", host:
"XYZ.localhost", referrer: "http://XYZ.localhost/"
这是我的 nginx 配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/var/log/nginx/access.log main;
error_log /usr/local/var/log/nginx/error.log;
server {
listen 80;
listen [::]:80;
server_name localhost;
location ~ ^/api/ {
proxy_pass http://$host:3000;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_redirect off;
rewrite ^/api(.*)$ break;
}
location / {
proxy_pass http://localhost:8080;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_redirect off;
}
}
include servers/*;
}
我听说在 proxy_pass 子句中使用变量会调用一些奇怪的 DNS 解析器巫术,所以我编辑了我的主机文件(/etc/hosts
on OS X),如下所示:
127.0.0.1 localhost *.localhost
255.255.255.255 broadcasthost
::1 localhost
经过无数次的实验,我最终成功了。我需要捕获子域并将其应用于代理 headers。此外,我需要一个上游块来强制 nginx 本身解析域。
upstream rails_api {
server 127.0.0.1:3000;
}
server {
listen 80;
listen [::]:80;
server_name ~^(?<subdomain>.+)\.localhost;
location ~ ^/api/ {
proxy_pass http://rails_api;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_set_header Host $subdomain.localhost:3000;
proxy_redirect off;
rewrite ^/api(.*)$ break;
}
location / {
proxy_pass http://localhost:8080;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_set_header Host $host;
proxy_redirect off;
}
}
我使用带有老化前端的整体式 Rails 4 应用程序。我的主要目标:在 VueJS 中构建一个新的独立前端,并将 Rails 服务器保持为 API,nginx 弥合了它们之间的差距。
在我的开发环境中设置原型一直是一个挑战。这就是我的立场:
- 当前应用使用通配符子域,因此我需要能够处理
XYZ.localhost
个 URL,无论 XYZ 是什么。 - Webpack 开发服务器位于
http://localhost:8080
。我打算默认将代理调用反向到此服务器。 - 遗留 Rails 开发服务器存在于
http://localhost:3000
。我打算在这里反转以/api/
开头的代理调用。它在大多数请求中都需要一个子域,因此http://clumsypanda.localhost/api/candy
应该代理到http://clumsypanda.localhost:3000/candy
.
我想我已经记下了前两个:当我访问 http://XYZ.localhost
时,nginx 为我提供 VueJS 内容。不过,我在调用 http://XYZ.localhost/api/whatever
时只收到 502 错误。具体来说,nginx 报告:
XYZ.localhost could not be resolved (3: Host not found), client: ::1, server: localhost, request: "POST /api/login HTTP/1.1", host: "XYZ.localhost", referrer: "http://XYZ.localhost/"
这是我的 nginx 配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/var/log/nginx/access.log main;
error_log /usr/local/var/log/nginx/error.log;
server {
listen 80;
listen [::]:80;
server_name localhost;
location ~ ^/api/ {
proxy_pass http://$host:3000;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_redirect off;
rewrite ^/api(.*)$ break;
}
location / {
proxy_pass http://localhost:8080;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_redirect off;
}
}
include servers/*;
}
我听说在 proxy_pass 子句中使用变量会调用一些奇怪的 DNS 解析器巫术,所以我编辑了我的主机文件(/etc/hosts
on OS X),如下所示:
127.0.0.1 localhost *.localhost
255.255.255.255 broadcasthost
::1 localhost
经过无数次的实验,我最终成功了。我需要捕获子域并将其应用于代理 headers。此外,我需要一个上游块来强制 nginx 本身解析域。
upstream rails_api {
server 127.0.0.1:3000;
}
server {
listen 80;
listen [::]:80;
server_name ~^(?<subdomain>.+)\.localhost;
location ~ ^/api/ {
proxy_pass http://rails_api;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_set_header Host $subdomain.localhost:3000;
proxy_redirect off;
rewrite ^/api(.*)$ break;
}
location / {
proxy_pass http://localhost:8080;
proxy_set_header Real-IP $remote_addr;
proxy_set_header Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header NginX-Proxy true;
proxy_set_header Host $host;
proxy_redirect off;
}
}