502 错误网关 - Rails 应用程序、Puma、Capistrano、Nginx
502 Bad Gateway - Rails App, Puma, Capistrano, Nginx
我在尝试部署我的 rails 应用程序时遇到 'Connection Refused' 错误。这是我从 /var/log/nginx/error.log
那里得到的消息
2020/01/03 20:40:44 [error] 8059#8059: *69 connect() to unix:/var/www/blog/shared/tmp/sockets/puma.sock failed (111: Connection refused) while connecting to upstream, client: 5.189.176.208, server: localhost, request: "GET / HTTP/1.0", upstream: "http://unix:/var/www/blog/shared/tmp/sockets/puma.sock:/500.html"
在 运行 cap production deploy
之后,puma 网络服务器监听一个套接字,但是当我访问我的 Ubuntu EC2 实例的 IP 地址时,我得到一个 nginx 502 Bad Gateway
留言。
我已经尝试 cap production deploy:restart
在本地机器上,在服务器上重新启动 nginx,并确保 sock 文件位置正确,但无济于事。错误日志不是很有帮助,所以我想知道如何诊断这个问题?我已经包含了一些配置文件,如果有任何提示,我将不胜感激。
puma.rb
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.11.2"
set :default_shell, '/bin/bash -l'
set :puma_conf, "/var/www/blog/shared/config/puma.rb"
set :application, "blog"
set :repo_url, "git@github.com:st4rgut22/blog.git"
set :linked_files, %w{config/master.key}
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, "/var/www/blog"
set :user_sudo, true
set:branch, 'master'
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
set :rbenv_map_bins, %w{rake gem bundle ruby rails puma pumactl}
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# append :linked_files, "config/database.yml"
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
# set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
/etc/nginx/sites-available/default(在部署目标上)
upstream app {
# Path to Puma SOCK file, as defined previously
server unix:/var/www/blog/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name localhost;
root /var/www/blog/public;
try_files $uri/index.html $uri @app;
location @app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
/var/www/blog/shared/config/puma.rb(在部署目标上)
# Change to match your CPU core count
workers 2
# Min and Max threads per worker
threads 1, 6
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env
# Set up socket location
#bind "unix://#{shared_dir}/sockets/puma.sock"
bind "unix:/var/www/blog/shared/tmp/sockets/puma.sock"
# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app
on_worker_boot do
require "active_record"
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end
/etc/nginx/nginx.conf(在部署目标上)
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
#
有两个 puma 配置文件,在第一个文件中您指定了端口而不是套接字。对生产环境有影响吗?
port ENV.fetch("PORT") { 3000 }
请仔细检查套接字文件以及 puma 进程在部署后是否存在。
ps ax|grep puma
ls -la /var/www/blog/shared/tmp/sockets/puma.sock
如果是,请查看 puma 和应用程序的日志文件
在下方评论讨论后更新:
部署后发现没有puma进程。 puma 的日志文件也是空的。这就是为什么我们决定通过转到应用程序根路径 /var/www/blog/current
并执行
在服务器上手动尝试 运行
bundle exec puma -b /var/www/blog/shared/tmp/sockets/puma.sock
结果是 STDOUT 上显示的权限错误。因此,在我们将 /var/www/blog/shared/config/puma.rb
中的日志和 pid 文件位置固定后问题就消失了,如下所示:
stdout_redirect "/var/www/shared/logs/puma.stdout.log", "/var/www/shared/logs/puma.stderr.log", true
pidfile "/var/www/blog/shared/tmp/pids/puma.pid"
state_path "/var/www/blog/shared/tmp/pids/puma.state"
我在尝试部署我的 rails 应用程序时遇到 'Connection Refused' 错误。这是我从 /var/log/nginx/error.log
2020/01/03 20:40:44 [error] 8059#8059: *69 connect() to unix:/var/www/blog/shared/tmp/sockets/puma.sock failed (111: Connection refused) while connecting to upstream, client: 5.189.176.208, server: localhost, request: "GET / HTTP/1.0", upstream: "http://unix:/var/www/blog/shared/tmp/sockets/puma.sock:/500.html"
在 运行 cap production deploy
之后,puma 网络服务器监听一个套接字,但是当我访问我的 Ubuntu EC2 实例的 IP 地址时,我得到一个 nginx 502 Bad Gateway
留言。
我已经尝试 cap production deploy:restart
在本地机器上,在服务器上重新启动 nginx,并确保 sock 文件位置正确,但无济于事。错误日志不是很有帮助,所以我想知道如何诊断这个问题?我已经包含了一些配置文件,如果有任何提示,我将不胜感激。
puma.rb
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.11.2"
set :default_shell, '/bin/bash -l'
set :puma_conf, "/var/www/blog/shared/config/puma.rb"
set :application, "blog"
set :repo_url, "git@github.com:st4rgut22/blog.git"
set :linked_files, %w{config/master.key}
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, "/var/www/blog"
set :user_sudo, true
set:branch, 'master'
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
set :rbenv_map_bins, %w{rake gem bundle ruby rails puma pumactl}
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# append :linked_files, "config/database.yml"
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
# set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
/etc/nginx/sites-available/default(在部署目标上)
upstream app {
# Path to Puma SOCK file, as defined previously
server unix:/var/www/blog/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name localhost;
root /var/www/blog/public;
try_files $uri/index.html $uri @app;
location @app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
/var/www/blog/shared/config/puma.rb(在部署目标上)
# Change to match your CPU core count
workers 2
# Min and Max threads per worker
threads 1, 6
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env
# Set up socket location
#bind "unix://#{shared_dir}/sockets/puma.sock"
bind "unix:/var/www/blog/shared/tmp/sockets/puma.sock"
# Logging
stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
# Set master PID and state locations
pidfile "#{shared_dir}/pids/puma.pid"
state_path "#{shared_dir}/pids/puma.state"
activate_control_app
on_worker_boot do
require "active_record"
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
end
/etc/nginx/nginx.conf(在部署目标上)
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
#
有两个 puma 配置文件,在第一个文件中您指定了端口而不是套接字。对生产环境有影响吗?
port ENV.fetch("PORT") { 3000 }
请仔细检查套接字文件以及 puma 进程在部署后是否存在。
ps ax|grep puma
ls -la /var/www/blog/shared/tmp/sockets/puma.sock
如果是,请查看 puma 和应用程序的日志文件
在下方评论讨论后更新:
部署后发现没有puma进程。 puma 的日志文件也是空的。这就是为什么我们决定通过转到应用程序根路径 /var/www/blog/current
并执行
bundle exec puma -b /var/www/blog/shared/tmp/sockets/puma.sock
结果是 STDOUT 上显示的权限错误。因此,在我们将 /var/www/blog/shared/config/puma.rb
中的日志和 pid 文件位置固定后问题就消失了,如下所示:
stdout_redirect "/var/www/shared/logs/puma.stdout.log", "/var/www/shared/logs/puma.stderr.log", true
pidfile "/var/www/blog/shared/tmp/pids/puma.pid"
state_path "/var/www/blog/shared/tmp/pids/puma.state"