I have Puma installed and running as a web server for a production Rails site, using Nginx as a reverse proxy.
I want to use init.d to manage the services for both Nginx and Puma. It appears to me like I've got it setup to do this, however when restarting Puma following an application change, the old changes are still being served.
What's the right was to both hot and cold restart Puma to serve new application changes?
The only way I can figure out to actually get new changes to apply is rebooting the server.
Obviously, that's not right, there's a command where, but when I run sudo /etc/init.d/puma restart
, it looks like it restarts (with a new PID and everything) but still no application changes are visible.
OS: Ubuntu 16.04
Nginx: 1.12.1
Puma: 3.11.0
Ruby: 2.5.0
Rails config
/path/to/app/Gemfile (excerpt)
gem 'puma', "~> 3.10"
/path/to/app/config/puma.rb
# Change to match your CPU core count
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
# Min and Max threads per worker
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count
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://#{app_dir}/tmp/sockets/myapp.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"
require 'erb'
begin
ActiveRecord::Base.connection.disconnect!
rescue
ActiveRecord::ConnectionNotEstablished
end
ActiveRecord::Base.establish_connection(YAML.safe_load(ERB.new(File.read("/path/to/app/config/database.yml")).result, [], [], true)[rails_env])
end
Puma Jungle
https://github.com/puma/puma/tree/master/tools/jungle/init.d
I ran the following to setup init.d with puma, following the instructions in the link above:
cd ~
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/init.d/puma
# Copy the init script to services directory
sudo mv puma /etc/init.d
sudo chmod +x /etc/init.d/puma
# Make it start at boot time.
sudo update-rc.d -f puma defaults
wget https://raw.githubusercontent.com/puma/puma/master/tools/jungle/init.d/run-puma
sudo mv run-puma /usr/local/bin
sudo chmod +x /usr/local/bin/run-puma
# Create an empty configuration file
sudo touch /etc/puma.conf
sudo /etc/init.d/puma add /path/to/app deploy /path/to/app/config/puma.rb /path/to/app/log/puma.log
touch /path/to/app/tmp/sockets/myapp.sock
mkdir -p /path/to/app/tmp/puma
nginx config
upstream myapp {
server unix:///path/to/app/tmp/sockets/myapp.sock;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name example.com;
root /path/to/app/public;
location / {
proxy_pass http://myapp;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_next_upstream error timeout invalid_header http_502;
}
}
Here's some of the puma output from init.d status and the puma.log
:
sudo /etc/init.d/puma status
● puma.service - LSB: Puma web server
Loaded: loaded (/etc/init.d/puma; bad; vendor preset: enabled)
Active: active (running) since Mon 2018-01-15 23:01:50 UTC; 25min ago
Docs: man:systemd-sysv-generator(8)
Process: 1119 ExecStart=/etc/init.d/puma start (code=exited, status=0/SUCCESS)
Tasks: 36
Memory: 309.6M
CPU: 11.541s
CGroup: /system.slice/puma.service
├─1240 puma 3.11.0 (unix:///path/to/app/tmp/sockets/myapp.sock) [myapp]
├─2013 puma: cluster worker 0: 1240 [myapp]
└─2017 puma: cluster worker 1: 1240 [myapp]
Jan 15 23:01:50 web2 systemd[1]: Starting LSB: Puma web server...
Jan 15 23:01:50 web2 puma[1119]: * => Running the jungle...
Jan 15 23:01:50 web2 puma[1119]: * --> Woke up puma /path/to/app
Jan 15 23:01:50 web2 puma[1119]: * user deploy
Jan 15 23:01:50 web2 puma[1119]: * log to /path/to/app/log/puma.log
Jan 15 23:01:50 web2 systemd[1]: Started LSB: Puma web server.
/path/to/app/log/puma.log
[3014] Puma starting in cluster mode...
[3014] * Version 3.11.0 (ruby 2.5.0-p0), codename: Love Song
[3014] * Min threads: 5, max threads: 5
[3014] * Environment: production
[3014] * Process workers: 2
[3014] * Phased restart available
[3014] * Listening on unix:///path/to/app/tmp/sockets/myapp.sock
[3014] Use Ctrl-C to stop
[3014] * Starting control server on unix:///tmp/puma-status-1515998276357-3014
[3014] - Worker 1 (pid: 3123) booted, phase: 0
[3014] - Worker 0 (pid: 3119) booted, phase: 0
[9913] Puma starting in cluster mode...
[9913] * Version 3.11.0 (ruby 2.5.0-p0), codename: Love Song
[9913] * Min threads: 5, max threads: 5
[9913] * Environment: production
[9913] * Process workers: 2
[9913] * Phased restart available
[9913] * Listening on unix:///path/to/app/tmp/sockets/myapp.sock
bundler: failed to load command: puma (/home/deploy/.rbenv/versions/2.5.0/bin/puma)
[3014] - Gracefully shutting down workers...
[1240] Puma starting in cluster mode...
[1240] * Version 3.11.0 (ruby 2.5.0-p0), codename: Love Song
[1240] * Min threads: 5, max threads: 5
[1240] * Environment: production
[1240] * Process workers: 2
[1240] * Phased restart available
[1240] * Listening on unix:///path/to/app/tmp/sockets/myapp.sock
[1240] Use Ctrl-C to stop
[1240] * Starting control server on unix:///tmp/puma-status-1516057427440-1240
[1240] - Worker 1 (pid: 2017) booted, phase: 0
[1240] - Worker 0 (pid: 2013) booted, phase: 0