ruby-on-railscapistranopumacapistrano3

Puma not creating pid file. Connection Refused error by Nginx on puma configuration


Puma socket does not exist under sockets folder yet puma is running under systemd service

tail -n10 /var/log/nginx/access.log

172.69.171.135 - - [15/Apr/2024:08:30:00 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:00 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:00 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:00 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:00 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:01 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:01 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:01 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:01 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"
172.69.171.135 - - [15/Apr/2024:08:30:01 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" "41.139.181.57"

tail -n10 /var/log/nginx/error.log Has No Output

/etc/nginx/conf.d/default.conf

upstream tuma_mizigo_client {
    server unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock;
}

server {
    listen 80;
    server_name tumamzigo.co.ke;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name tumamzigo.co.ke;

    root /var/www/tuma_mizigo_client/current/public;

    access_log /var/log/nginx/nginx_access.log;
    error_log /var/log/nginx/nginx_error.log;

    ssl_certificate /etc/letsencrypt/live/tumamzigo.co.ke/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tumamzigo.co.ke/privkey.pem;

    try_files $uri/index.html $uri @tuma_mizigo_client;

    location @tuma_mizigo_client {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://tuma_mizigo_client;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

tail -n5 /var/www/tuma_mizigo_client/shared/log/nginx_access.log

162.158.40.151 - - [09/Apr/2024:13:29:02 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
162.158.40.151 - - [09/Apr/2024:13:29:02 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
162.158.40.151 - - [09/Apr/2024:13:29:02 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
162.158.40.151 - - [09/Apr/2024:13:29:03 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
162.158.40.151 - - [09/Apr/2024:13:29:03 +0000] "GET / HTTP/1.1" 301 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"

tail -n5 /var/www/tuma_mizigo_client/shared/log/nginx_error.log - Has no output

cat /etc/systemd/system/tuma_mizigo_client_puma_production.service

[Unit]
Description=Tuma Mizigo Client Puma Production
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/var/www/tuma_mizigo_client/current
ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma.rb'
Restart=always

[Install]
WantedBy=multi-user.target

cap production puma:start

rvm 1.29.12 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
ruby-3.2.3
ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [aarch64-linux]
00:00 puma:start
      01 sudo /bin/systemctl start tuma_mizigo_client_puma_production
    ✔ 01 ubuntu@13.244.144.128 0.345s

sudo systemctl status tuma_mizigo_client_puma_production.service

● tuma_mizigo_client_puma_production.service - Tuma Mizigo Client Puma Production
     Loaded: loaded (/etc/systemd/system/tuma_mizigo_client_puma_production.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-04-15 08:44:54 UTC; 5s ago
   Main PID: 54194 (ruby)
      Tasks: 11 (limit: 18910)
     Memory: 77.5M
        CPU: 1.470s
     CGroup: /system.slice/tuma_mizigo_client_puma_production.service
             └─54194 "puma 6.4.2 (tcp://0.0.0.0:3000) [20240410205534]" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "">

Apr 15 08:44:54 ip-172-31-20-29 systemd[1]: Started Tuma Mizigo Client Puma Production.
Apr 15 08:44:55 ip-172-31-20-29 bash[54194]: Puma starting in single mode...
Apr 15 08:44:55 ip-172-31-20-29 bash[54194]: * Puma version: 6.4.2 (ruby 3.2.3-p157) ("The Eagle of Durango")
Apr 15 08:44:55 ip-172-31-20-29 bash[54194]: *  Min threads: 5
Apr 15 08:44:55 ip-172-31-20-29 bash[54194]: *  Max threads: 5
Apr 15 08:44:55 ip-172-31-20-29 bash[54194]: *  Environment: development
Apr 15 08:44:55 ip-172-31-20-29 bash[54194]: *          PID: 54194
Apr 15 08:44:56 ip-172-31-20-29 bash[54194]: * Listening on http://0.0.0.0:3000
Apr 15 08:44:56 ip-172-31-20-29 bash[54194]: Use Ctrl-C to stop
lines 1-19/19 (END)

tail -n10 /var/log/nginx/nginx_error.log

2024/04/15 08:33:39 [crit] 22197#22197: *23709 stat() "/var/www/tuma_mizigo_client/current/public/" failed (13: Permission denied), client: 34.65.177.84, server: tumamzigo.co.ke, request: "OPTIONS / HTTP/1.0", host: "13.244.144.128"
2024/04/15 08:33:39 [crit] 22197#22197: *23709 connect() to unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock failed (13: Permission denied) while connecting to upstream, client: 34.65.177.84, server: tumamzigo.co.ke, request: "OPTIONS / HTTP/1.0", upstream: "http://unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock:/", host: "13.244.144.128"
2024/04/15 08:33:39 [crit] 22197#22197: *23709 stat() "/var/www/tuma_mizigo_client/current/public/500.html/index.html" failed (13: Permission denied), client: 34.65.177.84, server: tumamzigo.co.ke, request: "OPTIONS / HTTP/1.0", upstream: "http://unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock/", host: "13.244.144.128"
2024/04/15 08:33:39 [crit] 22197#22197: *23709 stat() "/var/www/tuma_mizigo_client/current/public/500.html" failed (13: Permission denied), client: 34.65.177.84, server: tumamzigo.co.ke, request: "OPTIONS / HTTP/1.0", upstream: "http://unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock/", host: "13.244.144.128"
2024/04/15 08:33:39 [crit] 22197#22197: *23709 connect() to unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock failed (13: Permission denied) while connecting to upstream, client: 34.65.177.84, server: tumamzigo.co.ke, request: "OPTIONS / HTTP/1.0", upstream: "http://unix:///var/www/tuma_mizigo_client/current/tmp/sockets/puma.sock:/500.html", host: "13.244.144.128"

ls /var/www/tuma_mizigo_client/shared/tmp/sockets Shows nothing in the sockets folder

config/deploy/production.rb

set :port, 22
set :user, 'ubuntu'
set :application, 'tuma_mizigo_client'
set :deploy_to, '/var/www/tuma_mizigo_client'
set :deploy_via, :remote_cache
set :use_sudo, false

server '13.244.144.128',
  roles: [:web, :app, :db],
  port: fetch(:port),
  user: fetch(:user),
  primary: true

set :deploy_to, "/var/www/#{fetch(:application)}"
set :ssh_options, {
  forward_agent: true,
  auth_methods: %w(publickey),
  user: 'ubuntu',
  keys: %w[/Users/kelvin/.ssh/macbookpro2024.pem]
}

set :rails_env, :production
set :conditionally_migrate, true

set :default_env, {
  'SECRET_KEY_BASE': 'RANDOM STRING'
}

config/deploy.rb

# config valid for current version and patch releases of Capistrano
lock "~> 3.18.1"
require 'capistrano-db-tasks'

set :application, "tuma_mizigo_client"
set :repo_url, "git@github.com:username/appname.git"

set :use_sudo, false

# if you want to remove the local dump file after loading
set :db_local_clean, false

# Default branch is :master
ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

set :use_sudo, false
set :bundle_binsstubs, nil

set :rvm_map_bins, %w{gem rake ruby rails bundle puma pumactl sidekiq sidekiqctl}

# Default deploy_to directory is /var/www/my_app_name
set :app_path, "#{deploy_to}/current"

# 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, false

# Default value for :linked_files is []
append :linked_files, 'config/database.yml', 'config/secrets.yml', 'config/application.yml', 'config/sidekiq.yml'

# Default value for linked_dirs is []
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system', 'public/uploads'

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

# Default value for keep_releases is 5
# set :keep_releases, 5

## Capistrano DB Tasks
# if you want to remove the local dump file after loading
# set :db_local_clean, true

# if you want to remove the dump file from the server after downloading
# set :db_remote_clean, true

# if you are highly paranoid and want to prevent any push operation to the server
set :disallow_pushing, false

# If you want to import assets, you can change default asset dir (default = system)
# This directory must be in your shared directory on the server
set :assets_dir, %w(public/uploads)
set :local_assets_dir, %w(public/uploads)

### Puma Configuration ###
set :nginx_use_ssl, true
set :puma_workers, 2

### Sidekiq Configuration ###
SSHKit.config.command_map[:sidekiq] = "bundle exec sidekiq"
SSHKit.config.command_map[:sidekiqctl] = "bundle exec sidekiqctl"

# set :sidekiq_default_hooks, true
# set :sidekiq_pid, File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid') # ensure this path exists in production before deploying.
# # set :sidekiq_env, fetch(:rack_env, fetch(:rails_env))
# set :sidekiq_env, :production
# set :sidekiq_log, File.join(shared_path, 'log', 'sidekiq.log')
# set :sidekiq_config, File.join(shared_path, 'config', 'sidekiq.yml') # if you have a config/sidekiq.yml, do not forget to set this. 
# set :sidekiq_roles, :app
# set :sidekiq_processes, 1
# # sidekiq monit
# # set :sidekiq_monit_templates_path => 'config/deploy/templates'
# # set :sidekiq_monit_conf_dir => '/etc/monit/conf.d'
# # set :sidekiq_monit_use_sudo => true
# # :monit_bin => '/usr/bin/monit'
# # set :sidekiq_monit_default_hooks => true
# # set :sidekiq_monit_group => nil
# # set :sidekiq_service_name => "sidekiq_#{fetch(:application)}_#{fetch(:sidekiq_env)}" + (index ? "_#{index}" : '') 
# # set :sidekiq_user, 'ubuntu' #user to run sidekiq as

# set :sidekiq_service_unit_name => 'sidekiq'
# set :sidekiq_service_unit_user => :user # :system
# set :sidekiq_enable_lingering => true
# set :sidekiq_lingering_user => :user

set :puma_systemctl_user, :system

set :puma_enable_socket_service, true
set :puma_user, fetch(:user)
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{shared_path}/log/puma.error.log"
set :puma_error_log,  "#{shared_path}/log/puma.access.log"
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true 

Capfile

# Load DSL and set up stages
require 'capistrano/setup'

# Include default deployment tasks
require 'capistrano/deploy'

# Load the SCM plugin appropriate to your project:
#
# require 'capistrano/scm/hg'
# install_plugin Capistrano::SCM::Hg
# or
# require 'capistrano/scm/svn'
# install_plugin Capistrano::SCM::Svn
# or
require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git

# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
#   https://github.com/capistrano/rvm
#   https://github.com/capistrano/rbenv
#   https://github.com/capistrano/chruby
#   https://github.com/capistrano/bundler
#   https://github.com/capistrano/rails
#   https://github.com/capistrano/passenger
#
require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/rails'
require 'capistrano/bundler'
# require 'capistrano/rails/assets'
# require 'capistrano/rails/migrations'
require 'capistrano/puma'
require 'capistrano/sidekiq'
require 'capistrano/nginx'

# require 'capistrano/sidekiq/monit' #to require monit tasks # Only for capistrano3
# require 'capistrano/passenger'
install_plugin Capistrano::Puma  # Default puma tasks
install_plugin Capistrano::Puma::Workers  # if you want to control the workers (in cluster mode)
# install_plugin Capistrano::Puma::Jungle # if you need the jungle tasks
# install_plugin Capistrano::Puma::Monit  # if you need the monit tasks
install_plugin Capistrano::Puma::Nginx  # if you want to upload a nginx site template
install_plugin Capistrano::Sidekiq::Systemd
install_plugin Capistrano::Puma::Systemd  # if you use SystemD
install_plugin Capistrano::Nginx



# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Gemfile.lock

GIT
  remote: https://github.com/seuros/capistrano-puma.git
  revision: 2cc11846540489edda10d83e026c9bea04e6fab1
  specs:
    capistrano3-puma (6.0.0.beta.1)
      capistrano (~> 3.7)
      capistrano-bundler
      puma (>= 5.1, < 7.0)

GIT
  remote: https://github.com/seuros/capistrano-sidekiq.git
  revision: c8e1766b39478d5e9cfe10100d648dfd28c6c06b
  specs:
    capistrano-sidekiq (3.0.0.alpha.2)
      capistrano (>= 3.9.0)
      capistrano-bundler
      sidekiq (>= 6.0.6)

config/puma.rb

# This configuration file will be evaluated by Puma. The top-level methods that
# are invoked here are part of Puma's configuration DSL. For more information
# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.

# 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 that the worker count should equal the number of processors in production.
if ENV["RAILS_ENV"] == "production"
  require "concurrent-ruby"
  worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count })
  workers worker_count if worker_count > 1
  bind "unix:///var/www/tuma_mizigo_client/shared/tmp/sockets/puma.sock"
end

# Specifies the `worker_timeout` threshold that Puma will use to wait before
# terminating a worker in development environments.
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"

# 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" }

# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart

Solution

  • I believe that RAILS_ENV, the environment variable that tells Puma & Rails which environment it’s running in is not being set to production as is required to bind to the socket per your config/puma.rb. By default, this is set to development.

    You can set the environment by adding -e production to the puma command in the ExecStart of your service file.

    The full ExecStart line should look like this:

    ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma.rb -e production'