Last Updated: February 25, 2016
· snird

How to install nginx with passenger using chef

Hi everyone, so this one apparently is a bit tricky and not well explained anywhere else.
In my setup, I had to compile nginx 1.4.1 with passenger using the chef cookbook, all of that in a vagrant machine.
I'll assume some knowledge and understanding regarding chef and vagrant.

So we'll start with our main cookbook to use, the nginx cookbook provided by opscode official:

please note that we will use the "nginx::source" recipe so the cookbook dependencies for you are:
and depending on your system - apt or yum.

In order to install nginx with passenger we will have to compile it from source with the passenger flag, which the nginx cookbook will do automatically as we tell it to add the "passenger" module. So the recipe in use is "nginx::source". The final chef recipes list for vagrant should look something like that (if you don't use vagrant. it looks somewhat different in the chef run list):

config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks","brand_cookbooks"]
    chef.add_recipe 'apt' # or 'yum', depend on your machine
    chef.add_recipe 'build-essential'
    chef.add_recipe 'rvm::vagrant'
    chef.add_recipe 'rvm::system'
    chef.add_recipe 'rvm::gem_package'
    chef.add_recipe 'nginx::source'
    # some more recipes..

    chef.json = {
         # attributes configurations here - to be explaind

Now for the tricky part - apparently it doesn't explained in the nginx cookbook documentation for the most part, and using rvm there is a bug I couldn't know about, just after some time of debugging.

The chef.json attributes configuration

:rvm => {
    :default_ruby => "ruby-1.9.3-p429",
    :vagrant => {
        :system_chef_solo => '/opt/vagrant_ruby/bin/chef-solo'
:nginx => {
    :version => "1.4.1",
    :dir => "/etc/nginx",
    :log_dir => "/var/log/nginx",
    :binary => "/opt/nginx-1.4.1/sbin",
    :user => "develop",
    :init_style => "init",
    :source => {
        :modules => [
        :passenger => {
            :version => "3.0.21",
            :ruby => "/usr/local/rvm/rubies/ruby-1.9.3-p429/bin/ruby",
            :root => "/usr/local/rvm/gems/ruby-1.9.3-p429/gems/passenger-3.0.21"

So what's going on?


I choose to install a newer version than the default for the cookbook - 1.9.3-p429, and included the vagrant chef solo path so that after the new install vagrant will still know where it's original ruby is (for chef-solo provisioning use).


I'll skip the obvious - version, dir, etc' etc'



Array of modules to be installed, passenger is the important one for this guide. the others you might do or do not want to add.


Ok, here is why it's tricky. the nginx cookbook recipe for passenger is buggy. So you have to specifically say which version of passenger you want to install and then give it the directories of the passenger root and ruby binary.
Why? because the nginx cookbook assume usage of the default ruby coming with the vagrant machine, causing the paths to be wrong and the nginx compilation to fail.
pay attention to this part, the paths might be different on your system, change the path according to your passenger and ruby versions.

That's it

run yout vagrant machine chef provision and you'll have nginx compiled with passenger support. have fun.

3 Responses
Add your response

If I use ruby 2.0, passenger installation get error:

*** Running 'rake nginx CACHING=false' in /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.37/ext/nginx... ***
STDERR: /usr/lib/ruby/1.9.1/rubygems/dependency.rb:247:in to_specs': Could not find rake (>= 0) amongst [] (Gem::LoadError) from /usr/lib/ruby/1.9.1/rubygems/dependency.rb:256:into_spec'
from /usr/lib/ruby/1.9.1/rubygems.rb:1231:in gem' from /opt/chef/embedded/bin/rake:22:in<main>'

It becouse chef install own ruby 1.9, and when install passenger don't use default rvm ruby (2.0).
I rewrite this passenger attributes, but it don't help:

"passenger": {
"version": "4.0.37",
"root": "/usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.37",
"ruby": "/usr/local/rvm/rubies/ruby-2.0.0-p353/bin/ruby",
"gem_binary": "/usr/local/rvm/wrappers/ruby-2.0.0-p353/gem"

Can you help me?

over 1 year ago ·

@superp I am also having trouble with this setup, I got past the same error you had by setting :rvm_string in the :gem_package attribute to match :default_ruby like this:

:rvm => {
  :default_ruby => "ruby-2.1.1",
    :vagrant => {
      :system_chef_solo => "/opt/vagrant_ruby/bin/chef-solo"
    :gem_package => {
      :rvm_string => "ruby-2.1.1"

My nginx::passenger recipe found the right ruby then. But I'm still working on it, now I'm getting a timeout on the gem rake install:

==> web: Compiled Resource:
==> web: ------------------
==> web: # Declared in /tmp/vagrant-chef-2/chef-solo-1/cookbooks/nginx/recipes/passenger.rb:31:in `from_file'
==> web: 
==> web: gem_package("rake") do
==> web:   provider Chef::Provider::Package::RVMRubygems
==> web:   action :install
==> web:   retries 0
==> web:   retry_delay 2
==> web:   guard_interpreter :default
==> web:   package_name "rake"
==> web:   version "10.3.2"
==> web:   cookbook_name :nginx
==> web:   recipe_name "passenger"
==> web:   gem_binary "gem"
==> web: end
==> web: 
==> web: 
==> web: 
==> web: 
==> web: [2014-06-11T19:39:45+00:00] INFO: Running queued delayed notifications before re-raising exception
==> web: [2014-06-11T19:39:45+00:00] INFO: template[nginx.conf] sending reload action to service[nginx] (delayed)
==> web: [2014-06-11T19:39:45+00:00] ERROR: Running exception handlers
==> web: [2014-06-11T19:39:45+00:00] ERROR: Exception handlers complete
==> web: [2014-06-11T19:39:45+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> web: [2014-06-11T19:39:45+00:00] ERROR: gem_package[rake] (nginx::passenger line 31) had an error: Mixlib::ShellOut::CommandTimeout: Command timed out after 600s:
==> web: Command execeded allowed execution time, process terminated
==> web: ---- Begin output of bash -c "source /etc/profile.d/ && rvm ruby-2.1.1 do gem install rake -q --no-rdoc --no-ri -v \"10.3.2\"" ----
==> web: STDOUT: 
==> web: STDERR: Terminated
==> web: ---- End output of bash -c "source /etc/profile.d/ && rvm ruby-2.1.1 do gem install rake -q --no-rdoc --no-ri -v \"10.3.2\"" ----
==> web: Ran bash -c "source /etc/profile.d/ && rvm ruby-2.1.1 do gem install rake -q --no-rdoc --no-ri -v \"10.3.2\"" returned 
==> web: [2014-06-11T19:39:45+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.
over 1 year ago ·

I will try it as soon as possible.

over 1 year ago ·