How can I use unicorn as "rails s"? - ruby-on-rails

A new Rails project's Gemfile shows:
# Use unicorn as the app server
gem 'unicorn'
rails s --help shows:
Usage: rails server [mongrel, thin, etc] [options]
Yet, doing:
rails s unicorn
I get:
/Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/rack-1.4.5/lib/rack/handler.rb:63:in `require': cannot load such file -- rack/handler/unicorn (LoadError)
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/rack-1.4.5/lib/rack/handler.rb:63:in `try_require'
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/rack-1.4.5/lib/rack/handler.rb:16:in `get'
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/rack-1.4.5/lib/rack/server.rb:272:in `server'
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/railties-3.2.13/lib/rails/commands/server.rb:59:in `start'
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/railties-3.2.13/lib/rails/commands.rb:55:in `block in <top (required)>'
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/railties-3.2.13/lib/rails/commands.rb:50:in `tap'
from /Users/patrick/.rvm/gems/ruby-1.9.3-head#keynote/gems/railties-3.2.13/lib/rails/commands.rb:50:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
I've used unicorn in the past on other projects, but always had to run the unicorn command and specify a config file which is a bit of a pain. I am wondering how I can just simply make it work by using rails s...
Is this possible?

It looks like the unicorn-rails gem that #Dogbert mentioned can actually be used to make Unicorn the rails server handler.
Simply include gem "unicorn-rails" (and for Rails 4.2.4, gem "rack-handlers") in your Gemfile, run bundle install to install the gem, then you can run:
$ rails server unicorn
Although once unicorn-rails is installed, Unicorn should be the default app server so you could also just run rails server and it should use Unicorn (assuming you don't also have Thin or Mongrel in your Gemfile, in which case they may conflict and you might want to remove the ones you're not using).

A better option might just be to run the unicorn server directly.
bundle exec unicorn -p 3000 # default port is 8080

gem 'rack-handlers'
rails server unicorn

However the answer by Steven is the simplest way to do.
I run unicorn on development environment via a rake task:
lib/tasks/dev_unicorn.rake:
task :server do
# optional port parameter
port = ENV['PORT'] ? ENV['PORT'] : '3000'
puts 'start unicorn development'
# execute unicorn command specifically in development
# port at 3000 if unspecified
sh "cd #{Rails.root} && RAILS_ENV=development unicorn -p #{port}"
end
# an alias task
task :s => :server
run:
rake s
Reference http://jing.io

I don't think it is possible to use unicorn as 'rails s'. Use this -
Add gem 'unicorn' to gem file and run bundle install.
and then run any of the following commands -
$ unicorn -p 3000
or
$ unicorn_rails -p 3000

Related

Using Puma with Rails application

My configuration:
Rails 5.2.3
Ruby 2.6.3
rbenv
puma
capistrano
nginx
Ubuntu 18.04
I've been reading up on how to get all this setup and configured for deployment, but I don't seem to be able to find one place, that's got a clear and complete guide.
One of the things that confuse me the most is Puma. Some of the guides, do not mention anything about configuring Puma on the server, and all the instructions, reference the Puma Gem. A couple of other guides, discuss setting up and configuring Puma on the server, and modifications in the /etc/init folder.
Do I need to setup and configure Puma on the server, separately, before I can start using it for my Rails application?
No you do not need to set up and configure Puma on the server. Puma is a gem. So if you list it in your application's Gemfile, when you run bundle install for your Rails application, Puma will be installed automatically.
Any configuration for puma should go in your application, under config/puma.rb.
Does this answer your question?
When running Rails locally, just use config/puma.rb for your Puma config, and run Puma similar to the following:
RAILS_LOG_TO_STDOUT=1 bin/pumactl -F config/puma.rb start
The above will run Puma in the foreground. I personally use Overmind in development to run Puma, Webpacker, Sidekiq, and sometimes ngrok. That means I only need one iTerm tab for all of those.
To get bin/pumactl, run bin/bundle binstubs puma.
You could also run Puma using bin/rails server, but Puma recommends not doing that because not all of Puma's configuration options are available through that method.
A sample Puma config (based on what the capistrano3-puma gem produces [https://github.com/seuros/capistrano-puma/blob/v4.0.0/lib/capistrano/templates/puma.rb.erb]):
# frozen_string_literal: true
# config/puma.rb
require 'dotenv/load' # load a .env file for environment variables; gem 'dotenv-rails'
require 'nenv' # nicer ENV handling; gem 'nenv'
directory(File.expand_path('..', __dir__))
rackup(File.expand_path('../config.ru', __dir__))
environment(Nenv.rack_env || Nenv.rails_env || 'development')
# or without nenv
#environment(ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development')
threads(0, (Nenv.max_threads || 16).to_i)
# or without nenv
#threads(0, (ENV['MAX_THREADS'] || 16).to_i)
port((Nenv.port || 3_000).to_i)
# or without nenv
#port((ENV['PORT'] || 3_000).to_i)
workers 0
restart_command 'bundle exec puma'
prune_bundler
on_restart do
puts('Refreshing Gemfile...') # rubocop:disable Rails/Output
Nenv.bundle_gemfile = File.expand_path('../Gemfile', __dir__)
# or without nenv
#ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', __dir__)
end
For handling Puma using Capistrano, I recommend the capistrano3-puma gem (https://github.com/seuros/capistrano-puma). This gem has various tasks, one of which is puma:config which will create a puma.rb file in the shared directory. You would then add puma.rb to the :linked_files Capistrano config option:
# config/deploy.rb
append(:linked_files, 'puma.rb')
As for setting up a server (one you deploy to), you want to install Nginx and set that up to serve your Rails app. Again, the capistrano3-puma gem can come in handy for this, as it includes an Nginx plugin which provides a task to upload a config to your server. If you don't want to use that plugin, then I'd at least recommend looking at the template (https://github.com/seuros/capistrano-puma/blob/v4.0.0/lib/capistrano/templates/nginx_conf.erb) for that config, and then adapting it to your needs.
As #matt-v-from-toronto mentioned, Puma is installed as part of your app, and not separately on the server. Doing a bin/bundle install, or similar, will install Puma along with all of your other gems listed in your Gemfile.

Prevent puma from running in locally (ruby on rails)

I'm recently started to use Puma for my production server with nginx, however, when I now try to run my app locally, it tries to run Puma with all my production settings and fails. How can I prevent Puma from running locally?
AFAIK all I've done was added the puma gem to my gemfile, so I don't know how it's accessing my server config (I'm just not too knowledgeable in this area). I have it in my production group:
group :production do
gem 'pg'
gem 'rails_12factor'
gem 'puma'
end
Error:
→ rails s
=> Booting Puma
=> Rails 4.2.6 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[8917] Puma starting in cluster mode...
[8917] * Version 3.4.0 (ruby 2.0.0-p645), codename: Owl Bowl Brawl
[8917] * Min threads: 1, max threads: 6
[8917] * Environment: development
[8917] * Process workers: 1
[8917] * Phased restart available
[8917] * Listening on tcp://localhost:3000
[8917] Use Ctrl-C to stop
/rbenv/versions/2.0.0-p645/lib/ruby/gems/2.0.0/gems/puma-3.4.0/lib/puma/runner.rb:103:in `reopen': No such file or directory - /Users/me/mll/shared/log/puma.stdout.log (Errno::ENOENT)
Additionally, though less important to me right now, is it in my benefit to run Puma locally? If so, any tips/resources on how I can do that?
You need to put puma in your production group. Like this:
group :production do
gem 'puma'
end
That way puma will only be used on production and not development.
Update
Make sure that your bin/rails file looks like this:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
Having the exact same issue with Ben. I try to use web brick on local while developing and testing, and puma in production.
Gem file is perfectly define as puma only sits in production group. 'bin/rails' and 'config/application' are checked, same as #Răzvan Ciocănel suggested. Still boot with 'puma' on local.
At last, have a look into the 'bundle install' gem list, 'puma' is installed along with other 'production' gem. Run 'bundle install --without production' and now local will boot with web brick as ROR default.
I guess as long as puma is bundle installed, it will be loaded on local unless you config something to force it off. So the solution might be to remove the gem in the bundle list in development and test.
Rails 3 project (it keeps hanging around longer than expected...)
I changed from unicorn to puma in the production group of my gemfile.
group :production do
gem 'puma'
end
Then then when trying to run tests, or a dev server (which should have been thin) I got:
C:\Rails Projects\Rep>rails s
Could not find gem 'puma x86-mingw32' in any of the gem sources listed in your Gemfile or available on this machine.
Run `bundle install` to install missing gems.
After poking around a bit (including finding this question) I gave up and decided to go ahead and use puma in dev. I ran bundle install and tried running server and voila, thin was working again.
Then I realized I still only had it in the production group--I looked back at the bundle install and nothing was installed, puma still isn't installed. But now that bundle install has been run since the edit to the gemfile, everything works again.
C:\Rails Projects\Rep>rails s
=> Booting Thin
=> Rails 3.2.22.2 application starting in development on http://0.0.0.0:3000
So I guess the 'missing gem' error I wasn't because it was trying to actually run puma but rather some kind of bundler generated error due to unattempted gemfile? Just putting this out in case it speed things up for anyone in similar circumstances who ends up here.

`rails server puma` vs. `puma`

Some guides (example) recommend this to start one's webserver
bundle exec rails server puma
But I've always just started the server with puma directly
bundle exec puma
Does something special happening when firing up puma (or any other server) via rails server?
When you use rails s <server>, the server is launched from the Rails command and is aware of the Rails environment.
This makes possible, for example, to use any of the features and flags offered by the rails server command.
rails s --help
Usage: rails server [mongrel, thin, etc] [options]
-p, --port=port Runs Rails on the specified port.
Default: 3000
-b, --binding=ip Binds Rails to the specified ip.
Default: 0.0.0.0
-c, --config=file Use custom rackup configuration file
-d, --daemon Make server run as a Daemon.
-u, --debugger Enable ruby-debugging for the server.
-e, --environment=name Specifies the environment to run this server under (test/development/production).
Default: development
-P, --pid=pid Specifies the PID file.
Default: tmp/pids/server.pid
-h, --help Show this help message.
For instance, you can attach a debugger to the session passing --debugger or daemonize the server.
The second advantage is that you can version the Puma instance, since you will have to list the gem in the Gemfile. This is already true if you start it with bundle exec like you are doing.
Conversely, when you simply run $ puma (or $ bundle exec puma) you're not passing through the Rails system. Puma will try to find a rack bootstrap file and will use it (it works because Rails provides a config.ru script in the application root.
Generally speaking, there is no real difference if you don't need to pass specific options to the server. I like puma and I tend to use it in some projects even when on production we use Unicorn, thus running $ puma as a standalone command is handy because I don't need to add it to the Gemfile.
However, I would probably go with $ rails s puma if my entire stack uses Puma. This is also the command suggested in the documentation.

Faye setup in production

I've set up Faye on localhost, and works fine.
I'm now trying to deploy it on DigitalOcean VPS, with Cloud66 deployment service.
To run the command I use an "after_rails" hook.
rackup $RAILS_STACK_PATH/faye.ru -s thin -E production
This gives me the error:
Error during deployment: Error during after_rails hook: Server: not_specified. Failed to run command: /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in require': cannot load such file -- faye (LoadError) from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:inrequire' from /var/deploy/anabol/web_head/current/faye.ru:1:in block in <main>' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:55:ininstance_eval' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:55:in initialize' from /var/deploy/anabol/web_head/current/faye.ru:innew' from /var/deploy/anabol/web_head/current/faye.ru:in <main>' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:49:ineval' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:49:in new_from_string' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:40:inparse_file' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:277:in build_app_and_options_from_config' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:199:inapp' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:314:in wrapped_app' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:250:instart' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:141:in start' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/bin/rackup:4:in' from /usr/local/bin/rackup:23:in load' from /usr/local/bin/rackup:23:in'
github repo:
https://github.com/gwuix2/anabol
Any suggestions what could be the problem? Don't know where to start.
I've written up some documentation on how to solve this problem in case anyone else runs into it. You can find it here: http://community.cloud66.com/articles/faye-on-cloud-66
Disclaimer: I work for Cloud 66.
Cloud 66 Support solved my problem:
Hi there,
We run faye on our own stack. We actually run it behind thin - and monitor it as a process on the stack. The way we do this is with four files - see their details below:
1) RAILS_ROOT/.cloud66/deploy_hooks.yml
production:
before_rails:
- source: /.cloud66/files/add_thin_and_faye.sh
destination: ~/add_thin_and_faye.sh
target: rails
execute: true
sudo: true
apply_during: build_only
run_on: all_servers
2) RAILS_ROOT/.cloud66/files/add_thin_and_faye.sh
#!/bin/bash
sudo gem install thin --no-ri --no-rdoc
sudo gem install faye --no-ri --no-rdoc
3) RAILS_ROOT/Procfile
faye: thin -R $RAILS_STACK_PATH/faye/config.ru start
4) RAILS_ROOT/faye/config.ru
require 'faye'
faye_server = Faye::RackAdapter.new(:mount => '/your_faye_mount', :timeout => 45)
Faye::WebSocket.load_adapter('thin')
faye_server.listen(<<PUT-YOUR-PORT-HERE>>)
Note that for part 4) the settings will be different based on your requirements of course.
If you follow the setup above, you'll have faye running alongside your stack, and it will be available as a process on your stack.

How define his own server with Rails 3

I want use always thin when I start my rails server in development mode.
By default it webrick to use. So I add thin in my Gemfile
gem 'thin', :group => 'development'
Now If I want use it to launch my server in development mode I mandatory define it.
bundle exec rails s thin
If I don't define it, it's always use webrick. So How define using thin by default ?
Instead of rails s just type :
>> thin start -p 3000
Where 3000 is the number of your port.
You can also specify an enviornment :
>> thin start -e production
Assuming you are using bundler 1.0.x and your gems is vendorized:
bundle exec vendor/ruby/1.9.1/bin/thin start

Resources