部署 Rails Api + Vuejs 使用 docker 部署,点击链接可以访问,页面刷新 nginx 报错 502

Sylor-huang · 2020年10月05日 · 最后由 Sylor-huang 回复于 2020年10月05日 · 804 次阅读

Rails 提供 后端 api,默认端口为 3002

vuejs 编写前端 部署采用 puma + nginx + docker

现在使用 docker 部署到阿里云后,配置了 nginx,点击相应的链接可以访问页面,但是刷新该页面,会报错 502:

2020/10/05 03:45:31 [error] 8202#8202: *137 connect() to unix:/home/udasker/udaskweb/tmp/sockets/puma.sock failed (111: Connection refused) while connecting to upstream, client: 185.191.171.23, server: www.udask.net, request: "GET /robots.txt HTTP/1.1", upstream: "http://unix:/home/udasker/udaskweb/tmp/sockets/puma.sock:/50x.html", host: "www.udask.net"

nginx 配置:

user user_name;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
  worker_connections 1024;
  # multi_accept on;
}
http {
      upstream app {
       server unix:/home/udasker/udaskweb/tmp/sockets/puma.sock;
      }
     server {
        listen 443 ssl;
        server_name www.udask.net udask.net;
        ssl on;
        ssl_certificate /etc/nginx/cert/udask.pem;
        ssl_certificate_key /etc/nginx/cert/udask.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers d...;
        ssl_prefer_server_ciphers on;
        root   /home/udasker/udaskweb/front_web/dist;   #这里是vuejs的build文件
        try_files $uri/index.html $uri @app;
        location ~ ^/api/ {
                set $backend "127.0.0.1";
                proxy_pass http://$backend:3002;    #后端rails服务 使用3002端口
                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;
            }
        location @app {
            proxy_pass http://app;
            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 Host $http_host;
            proxy_redirect off;
            root   /home/udasker/udaskweb/front_web/dist;
            autoindex_exact_size on;
            autoindex_localtime on;
            proxy_read_timeout 240s;
        }      

}
server {
    listen 80;
    server_name  www.udask.net udask.net;
    rewrite ^(.*)$ https://$host$1 permanent;
}

}

以上 nginx 配置哪里出现问题了呢?请大家指导,非常感谢~

upstream app 指向的是 sock file,改成 3002 端口。

感觉 location @app 是不是可以整个删掉,前面已经设置了 root 和 try_files 了。

@Rei 您的意思是 upstream app 不用 puma.sock,直接指定"localhost: 3002"的吗?我这个现在是前后分离,前端调用 rails api,不需要特意使用 location /api 的吗?非常感谢~

如果您方便的话,可以帮我提供下示例代码的吗?测试了快 1 天了,实在是搞不来...

版本一,Rails 只处理 /api 路径,404 由 nginx 处理(可以设置用 dist 里面的 404 页面):

upstream app {
  server 127.0.0.1:3002
}
server {
  listen 443 ssl;
  server_name www.udask.net udask.net;
  ssl on;
  ssl_certificate /etc/nginx/cert/udask.pem;
  ssl_certificate_key /etc/nginx/cert/udask.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers d...;
  ssl_prefer_server_ciphers on;
  root   /home/udasker/udaskweb/front_web/dist;   #这里是vuejs的build文件
  try_files $uri/index.html $uri;

  location ~ ^/api/ {
    proxy_pass http://app;    #后端rails服务 使用3002端口
    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 X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    autoindex_exact_size on;
    autoindex_localtime on;
    proxy_read_timeout 240s;
  }
}

版本二,Rails 接管 404 页面:

upstream app {
  server 127.0.0.1:3002
}

server {
  listen 443 ssl;
  server_name www.udask.net udask.net;
  ssl on;
  ssl_certificate /etc/nginx/cert/udask.pem;
  ssl_certificate_key /etc/nginx/cert/udask.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers d...;
  ssl_prefer_server_ciphers on;
  root   /home/udasker/udaskweb/front_web/dist;   #这里是vuejs的build文件
  try_files $uri/index.html $uri @app;

  location @app {
    proxy_pass http://app;
    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 Host $http_host;
    proxy_set_header NginX-Proxy   true;
    proxy_redirect off;
    root   /home/udasker/udaskweb/front_web/dist;
    autoindex_exact_size on;
    autoindex_localtime on;
    proxy_read_timeout 240s;
  }      
}

没有实操,不一定对。

@Rei 非常感谢您的回复。

我用您的第一种方法测试,nginx 出现 500 错误:

2020/10/05 07:31:09 [error] 10091#10091: *20 rewrite or internal redirection cycle while internally redirecting to "/static/favicon.ico", client: 27.17.148.30, server: udask.net, request: "GET /static/favicon.ico HTTP/1.1", host: "www.udask.net", referrer: "https://www.udask.net/"
2020/10/05 07:32:26 [error] 10091#10091: *22 rewrite or internal redirection cycle while internally redirecting to "/css/app.app.css", client: 27.17.148.30, server: udask.net, request: "GET /css/app.app.css HTTP/1.1", host: "www.udask.net", referrer: "https://www.udask.net/"
...

使用第二种方法测试,点击链接可以跳转,但是页面刷新,puma 会报错 404:

I, [2020-10-05T07:35:37.778810 #9729]  INFO -- : [aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] Started GET "/articles" for 27.17.148.30 at 2020-10-05 07:35:37 +0000
F, [2020-10-05T07:35:37.779968 #9729] FATAL -- : [aeb19f54-f603-4bed-9ad9-bb41c08d1b3f]   
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] ActionController::RoutingError (No route matches [GET] "/articles"):
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f]   
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] actionpack (6.0.2.2) lib/action_dispatch/middleware/debug_exceptions.rb:36:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] actionpack (6.0.2.2) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] railties (6.0.2.2) lib/rails/rack/logger.rb:38:in `call_app'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] railties (6.0.2.2) lib/rails/rack/logger.rb:26:in `block in call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] activesupport (6.0.2.2) lib/active_support/tagged_logging.rb:80:in `block in tagged'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] activesupport (6.0.2.2) lib/active_support/tagged_logging.rb:28:in `tagged'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] activesupport (6.0.2.2) lib/active_support/tagged_logging.rb:80:in `tagged'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] railties (6.0.2.2) lib/rails/rack/logger.rb:26:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] actionpack (6.0.2.2) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] request_store (1.5.0) lib/request_store/middleware.rb:19:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] actionpack (6.0.2.2) lib/action_dispatch/middleware/request_id.rb:27:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] rack (2.2.2) lib/rack/runtime.rb:22:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] actionpack (6.0.2.2) lib/action_dispatch/middleware/executor.rb:14:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] rack (2.2.2) lib/rack/sendfile.rb:110:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] actionpack (6.0.2.2) lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] railties (6.0.2.2) lib/rails/engine.rb:526:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] puma (4.3.1) lib/puma/configuration.rb:228:in `call'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] puma (4.3.1) lib/puma/server.rb:681:in `handle_request'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] puma (4.3.1) lib/puma/server.rb:472:in `process_client'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] puma (4.3.1) lib/puma/server.rb:328:in `block in run'
[aeb19f54-f603-4bed-9ad9-bb41c08d1b3f] puma (4.3.1) lib/puma/thread_pool.rb:134:in `block in spawn_thread'
I, [2020-10-05T07:35:40.286506 #9729]  INFO -- : [678c23e8-b713-46dd-8499-2dbd37db9165] =======no_method_error:undefined method `[]' for nil:NilClass
I, [2020-10-05T07:35:40.287005 #9729]  INFO -- : [678c23e8-b713-46dd-8499-2dbd37db9165] Completed 200 OK in 40045ms (Views: 0.2ms | ActiveRecord: 0.7ms | Allocations: 21844)

dist 里面是不是只有一个 index.html 页面,其它都是 js css?

upstream app {
  server 127.0.0.1:3002
}
server {
  listen 443 ssl;
  server_name www.udask.net udask.net;
  ssl on;
  ssl_certificate /etc/nginx/cert/udask.pem;
  ssl_certificate_key /etc/nginx/cert/udask.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers d...;
  ssl_prefer_server_ciphers on;
  root   /home/udasker/udaskweb/front_web/dist;   #这里是vuejs的build文件
  try_files $uri/index.html $uri index.html; # <- 这里加 index.html 到末尾

  location ~ ^/api/ {
    proxy_pass http://app;    #后端rails服务 使用3002端口
    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 X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    autoindex_exact_size on;
    autoindex_localtime on;
    proxy_read_timeout 240s;
  }
}

dist 文件夹里有 css , static 文件夹和 index.html,static 文件夹里其他的一些静态文件,包含图片,字体和 js 文件等

按您所说的,添加了 index.html 后,nginx 出现了 500 错误:

2020/10/05 07:55:05 [error] 10589#10589: *1 rewrite or internal redirection cycle while internally redirecting to "index.html", client: 27.17.148.30, server: udask.net, request: "GET /classifies HTTP/1.1", host: "www.udask.net"

试试

try_files $uri /index.html;

可以了,可以了,@Rei, 就是按您说的修改为 $uri /index.html;

非常感谢您~

看来是 /index.html 不用绝对路径会造成循环重定向。

谢谢大佬,实在对 nginx 不熟,花费了好长时间解决不了,在网上也没找到相应的例子。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号