Skip to content

Instantly share code, notes, and snippets.

@Epictetus
Forked from 0x263b/example.md
Created May 13, 2022 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Epictetus/a0fb82b909a00eed1e8fe6ffa07ea07f to your computer and use it in GitHub Desktop.
Save Epictetus/a0fb82b909a00eed1e8fe6ffa07ea07f to your computer and use it in GitHub Desktop.
Puma + Nginx + Upstart

Assuming your domain is example.com and your apps root directory is /var/www/example.com

Puma

cd into the root directory and create directories var/run, var/log. This is where your domain socket and server logs will be stored.

Next create a file puma.rb with the following

threads 1, 6
workers 1

root = "#{Dir.getwd}"
 
bind "unix://#{root}/var/run/puma.sock"

stdout_redirect "#{root}/var/log/puma.stdout.log", "#{root}/var/log/puma.stderr.log", true

pidfile "#{root}/var/run/puma.pid"
state_path "#{root}/var/run/state"

rackup "#{root}/config.ru"

This will run your app as declared in config.ru. A sinatra example:

require './app'
run Sinatra::Application

Upstart

Next, we need an upstart service to run the app on startup.

$ sudo nano /etc/init/puma-manager.conf

Paste this code

description "Manages the set of puma processes"

# This starts upon bootup and stops on shutdown
start on runlevel [2345]
stop on runlevel [06]

env PUMA_CONF="/etc/puma.conf"

pre-start script
  for i in `cat $PUMA_CONF`; do
    app=`echo $i | cut -d , -f 1`
    logger -t "puma-manager" "Starting $app"
    cd $app
    exec bundle exec puma -e production --config puma.rb
  done
end script

This will read a file /etc/puma.conf, and run each app in the directories listed. An example config:

/var/www/example.com
/var/www/example.org

Now run the service

$ sudo service puma-manager start

Nginx

Create a Virtual Host in nginx

$ sudo nano /etc/nginx/sites-available/example.com

The following config will listen for connections to example.com and redirect them to the unix domain socket running in your app's directory.

# Unix domain socket
upstream puma_example {
	server unix:/var/www/example.com/var/run/puma.sock fail_timeout=0;
}

server {
	listen 80;
	
	root /var/www/example.com/public;
	access_log /var/www/example.com/var/log/nginx_access.log;
	error_log /var/www/example.com/var/log/nginx_error.log;

	server_name example.com www.example.com;

	location / {
		try_files $uri @example;
	}

	location @example {
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_pass http://puma_example; # pass to domain socket
	}
}

Enable the site in nginx, and restart

$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
$ sudo service nginx restart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment