I'm getting a 'Connection Refused' error when attempting to deploy my rails app. This is the message I get from /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"
After running cap production deploy
, puma web server listens to a socket, but when I access the IP address of my Ubuntu EC2 Instance I get a nginx 502 Bad Gateway
message.
I have tried cap production deploy:restart
on local machine, restarting nginx on the server, and making sure the sock file location is correct, but to no avail. The error log is not very helpful, so I was wondering how I could diagnose this problem? I have included some configuration files and would appreciate any tips.
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, "[email protected]: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 (on deploy target)
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 (on deploy target)
# 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 (on deploy target)
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;
#
There are two puma config files, in the first one you've specified a port instead of a socket. Does it affect the production environment?
port ENV.fetch("PORT") { 3000 }
Please double check that the socket file, as well as the puma process, exists after a deploy.
ps ax|grep puma
ls -la /var/www/blog/shared/tmp/sockets/puma.sock
If so have a look at the puma's and application's log files
It turned out that there is no puma process after a deployment. The puma's log files were empty too. That's why we decided to try run it manually on the server by going to the applications root path /var/www/blog/current
and executing
bundle exec puma -b /var/www/blog/shared/tmp/sockets/puma.sock
The result was a permission error shown on the STDOUT. So the problem disappeared after we fixed log and pid files location in /var/www/blog/shared/config/puma.rb
as follows:
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"