What an adventure! Seriously, look at that mouthful. On the tail end of spending two full days moving 2u.fm onto this setup with hours of hair-pulling (yay!) so 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):
1 2 3 4 5 |
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):
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:
1 2 3 4 |
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: …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/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:
1 2 3 |
#!/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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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.