here’s a quick recap to hopefully save you some trouble.
First you need chruby. chruby is an extremely lightweight ruby switching tool. Going from RVM to rbenv to chruby feels like moving from a Escalade to a Camry to a Lotus Elise. It’s slightly less cushy, but faster and leaner (and therefore easier to debug and less finicky). You should be able to install it easily from their instructions.
I decided to go full bore and blow away rbenv on my local machine as well so I would be using the same thing on both ends. If you are on a mac you can do that with:
brew install chruby
Now, I ran into some trouble building Rubinius using ruby-build (see this ticket on github) but my bet is typically it would work. Nonetheless for the server, it is probably best to build from source if you want an edge version anyway as it is easier to debug. Lets also install clang and use that (clang is generally faster and uses less memory than gcc):
apt-get install clang
git clone git://github.com/rubinius/rubinius.git
cd rubinius
./configure --prefix=/opt/rubies/rbx-2.0.0-master --cc=clang --cxx=clang++
rake install
chruby checks in /opts/rubies for your ruby version by default. On my server (and local box) I use zsh so I put this in my ~/.zshrc (or ~/.bashrc for bash users):
source /usr/local/share/chruby/chruby.sh
source /usr/local/share/chruby/auto.sh
chruby rbx
This installs chruby, the auto line will change rubies as you cd around, and the last line sets your default ruby to Rubinius (and is not required).
Now set up the git repo and website directory:
git init --bar /var/git/app_name.git
mkdir /var/www/app_name/web
mkdir /var/www/app_name/web/shared
mkdir /var/www/app_name/web/shared
My Capistrano config/deploy.rb has important bits: …
# ssh forwarding and shell
set :default_run_options, { :pty => true }
set :ssh_options, { :forward_agent => true }
...
# chruby
# set :bundle_flags, "--verbose"
set :ruby_version, "rbx"
set :chrub_script, "/usr/local/share/chruby/chruby.sh"
set :set_ruby_cmd, ". #{chrub_script} && chruby #{ruby_version}"
set(:bundle_cmd) { "#{set_ruby_cmd} && RAILS_ENV=#{rails_env} exec bundle" }
# Roles
role :web, domain
role :app, domain
role :db, domain, :primary => true # This is where Rails migrations will run
after 'deploy:update_code', 'deploy:migrate'
after 'deploy:update', 'deploy:symlink_attachments'
after 'deploy:update', 'deploy:symlink_tmp'
after 'deploy:update', 'deploy:clear_caches'
after 'deploy:update', 'deploy:cleanup'
# Run rake tasks
def run_rake(task, options={}, &block)
command = "cd #{latest_release} && #{bundle_cmd} rake #{task}"
run(command, options, &block)
end
namespace :puma do
task :start, :except => { :no_release => true } do
run "/etc/init.d/puma start #{application}"
end
after "deploy:start", "puma:start"
task :stop, :except => { :no_release => true } do
run "/etc/init.d/puma stop #{application}"
end
after "deploy:stop", "puma:stop"
task :restart, roles: :app do
run "/etc/init.d/puma restart #{application}"
end
after "deploy:restart", "puma:restart"
end
namespace :deploy do
task :symlink_attachments do
run "ln -nfs #{shared_path}/attachments #{release_path}/public/attachments"
end
task :symlink_tmp do
run "rm -rf #{release_path}/tmp"
run "ln -nfs #{shared_path}/tmp #{release_path}/tmp"
run "chmod 775 #{shared_path}/tmp"
end
task :clear_caches do
run "echo 'flush_all' | nc localhost 11211" # memcached
run_rake "tmp:cache:clear >/dev/null 2>&1"
end
end
… and the config/puma.rb:
#!/usr/bin/env puma
basedir = '/var/www/APP_NAME/web/current'
directory "#{basedir}"
environment 'production'
daemonize true
bind "unix://#{basedir}/tmp/puma/puma.sock"
pidfile "#{basedir}/tmp/puma/pid"
state_path "#{basedir}/tmp/puma/state"
threads 4, 48
preload_app!
activate_control_app
Notes:
Make sure #{basedir}/tmp/puma/ is there, but don’t create any files inside it
Make sure the account that runs deploy.rb/puma is the owner of your web directory and shared directory
Turn off daemonizing and socket for debugging
I had to add chruby to the init.d script. It’s massive, so here’s a gist.
Also some changes for /usr/local/bin/run-puma:
#!/bin/zsh
app=$1; config=$2; log=$3;
source /usr/local/share/chruby/chruby.sh && chruby rbx && cd $app && puma --debug -C $config 2>&1 >> $log
Finally, nginx should connect like normally:
upstream APP_puma {
server unix:///var/www/APP/web/current/tmp/puma/puma.sock;
}
server {
listen 80 default;
server_name APP.com www.APP.com;
root /var/www/APP/web/current/public;
location ~ ^/(assets|fonts|images|attachments)/?|favicon.ico {
root /var/www/APP/web/current/public;
expires max;
break;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass http://APP_puma;
}
}
To see all the files in full, check out this gist:
https://gist.github.com/natew/6207594
from http://natewienert.com/rubinius-plus-puma-plus-chruby-plus-capistrano-on-ubuntu
First you need chruby. chruby is an extremely lightweight ruby switching tool. Going from RVM to rbenv to chruby feels like moving from a Escalade to a Camry to a Lotus Elise. It’s slightly less cushy, but faster and leaner (and therefore easier to debug and less finicky). You should be able to install it easily from their instructions.
I decided to go full bore and blow away rbenv on my local machine as well so I would be using the same thing on both ends. If you are on a mac you can do that with:
brew install chruby
Now, I ran into some trouble building Rubinius using ruby-build (see this ticket on github) but my bet is typically it would work. Nonetheless for the server, it is probably best to build from source if you want an edge version anyway as it is easier to debug. Lets also install clang and use that (clang is generally faster and uses less memory than gcc):
apt-get install clang
git clone git://github.com/rubinius/rubinius.git
cd rubinius
./configure --prefix=/opt/rubies/rbx-2.0.0-master --cc=clang --cxx=clang++
rake install
chruby checks in /opts/rubies for your ruby version by default. On my server (and local box) I use zsh so I put this in my ~/.zshrc (or ~/.bashrc for bash users):
source /usr/local/share/chruby/chruby.sh
source /usr/local/share/chruby/auto.sh
chruby rbx
This installs chruby, the auto line will change rubies as you cd around, and the last line sets your default ruby to Rubinius (and is not required).
Now set up the git repo and website directory:
git init --bar /var/git/app_name.git
mkdir /var/www/app_name/web
mkdir /var/www/app_name/web/shared
mkdir /var/www/app_name/web/shared
My Capistrano config/deploy.rb has important bits: …
# ssh forwarding and shell
set :default_run_options, { :pty => true }
set :ssh_options, { :forward_agent => true }
...
# chruby
# set :bundle_flags, "--verbose"
set :ruby_version, "rbx"
set :chrub_script, "/usr/local/share/chruby/chruby.sh"
set :set_ruby_cmd, ". #{chrub_script} && chruby #{ruby_version}"
set(:bundle_cmd) { "#{set_ruby_cmd} && RAILS_ENV=#{rails_env} exec bundle" }
# Roles
role :web, domain
role :app, domain
role :db, domain, :primary => true # This is where Rails migrations will run
after 'deploy:update_code', 'deploy:migrate'
after 'deploy:update', 'deploy:symlink_attachments'
after 'deploy:update', 'deploy:symlink_tmp'
after 'deploy:update', 'deploy:clear_caches'
after 'deploy:update', 'deploy:cleanup'
# Run rake tasks
def run_rake(task, options={}, &block)
command = "cd #{latest_release} && #{bundle_cmd} rake #{task}"
run(command, options, &block)
end
namespace :puma do
task :start, :except => { :no_release => true } do
run "/etc/init.d/puma start #{application}"
end
after "deploy:start", "puma:start"
task :stop, :except => { :no_release => true } do
run "/etc/init.d/puma stop #{application}"
end
after "deploy:stop", "puma:stop"
task :restart, roles: :app do
run "/etc/init.d/puma restart #{application}"
end
after "deploy:restart", "puma:restart"
end
namespace :deploy do
task :symlink_attachments do
run "ln -nfs #{shared_path}/attachments #{release_path}/public/attachments"
end
task :symlink_tmp do
run "rm -rf #{release_path}/tmp"
run "ln -nfs #{shared_path}/tmp #{release_path}/tmp"
run "chmod 775 #{shared_path}/tmp"
end
task :clear_caches do
run "echo 'flush_all' | nc localhost 11211" # memcached
run_rake "tmp:cache:clear >/dev/null 2>&1"
end
end
… and the config/puma.rb:
#!/usr/bin/env puma
basedir = '/var/www/APP_NAME/web/current'
directory "#{basedir}"
environment 'production'
daemonize true
bind "unix://#{basedir}/tmp/puma/puma.sock"
pidfile "#{basedir}/tmp/puma/pid"
state_path "#{basedir}/tmp/puma/state"
threads 4, 48
preload_app!
activate_control_app
Notes:
Make sure #{basedir}/tmp/puma/ is there, but don’t create any files inside it
Make sure the account that runs deploy.rb/puma is the owner of your web directory and shared directory
Turn off daemonizing and socket for debugging
I had to add chruby to the init.d script. It’s massive, so here’s a gist.
Also some changes for /usr/local/bin/run-puma:
#!/bin/zsh
app=$1; config=$2; log=$3;
source /usr/local/share/chruby/chruby.sh && chruby rbx && cd $app && puma --debug -C $config 2>&1 >> $log
Finally, nginx should connect like normally:
upstream APP_puma {
server unix:///var/www/APP/web/current/tmp/puma/puma.sock;
}
server {
listen 80 default;
server_name APP.com www.APP.com;
root /var/www/APP/web/current/public;
location ~ ^/(assets|fonts|images|attachments)/?|favicon.ico {
root /var/www/APP/web/current/public;
expires max;
break;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass http://APP_puma;
}
}
To see all the files in full, check out this gist:
https://gist.github.com/natew/6207594
from http://natewienert.com/rubinius-plus-puma-plus-chruby-plus-capistrano-on-ubuntu