Engine Yard Developer Center

Customize Unicorn

Unicorn does not employ keep files for its configuration file. This page describes how to customize Unicorn without a keep file.

The process is:

  1. Create an alternate Unicorn configuration file.
  2. Start Unicorn with Bundler instead of running the system Unicorn.

To create the customized Unicorn configuration file and restart Unicorn

  1. Add this line to the file /data/_myapp_/shared/config/env.custom (where myapp is the name of your application):

    UNICORN_CONF="/data/_myapp_/shared/config/custom_unicorn.rb" 

    This specifies an alternate configuration file for Unicorn.

    Note: If you are using env_vars, then use the env_vars recipe to customize the environment variable. If you are already using the env_vars recipe, it will override your settings here. Use the recipe to customize your Unicorn settings.

  2. Copy /data/_myapp_/shared/config/unicorn.rb to /data/_myapp_/shared/config/custom_unicorn.rb.

  3. Edit the /data/_myapp_/shared/config/custom_unicorn.rb with the customizations that you want.

  4. Restart Unicorn so that the customizations take effect:

    /engineyard/bin/app_myapp reload 

To start Unicorn in Bundler

  1. Add the Unicorn gem to your Gemfile:

    gem 'unicorn' 
  2. Run these commands to update your Gemfile.lock:

    bundle install 

    git commit -a -m "Gemfile updated for Unicorn"
    git push origin

If you have feedback or questions about this page, add a comment below. If you need help, submit a ticket with Engine Yard Support.

Was this article helpful?
8 out of 8 found this helpful
Have more questions? Submit a request

Comments

  • Avatar
    Petteri Räty

    The last example file talks about Trinidad so someone needs to fix this page.

  • Avatar
    Keri Meredith

    Hi Petteri, thank you for your feedback on our documentation. This page has been updated. kjm

  • Avatar
    Justin Turner Arthur

    I've successfully used step 1 to load a custom unicorn configuration. However, can you please explain why step 2 is necessary? What happens or doesn't happen when the application has its own unicorn gem? Thanks!

  • Avatar
    J. Austin Hughey

    Hi Justin,

    When you use Bundler, there are at least two sets of gems on your system at any time: system gems, and gems specific to your application. The question then becomes, when launching the application, which set do you use? If you use Bundler properly, only the gems built specifically for your application should be loaded and used when it spawns up. If you use system gems by not specifying "bundle exec", you'll end up with probably old versions of certain gems, including dependencies, being loaded, which can cause things not to start or to bug out. Imagine trying to start your application and an old version of a gem from, say, 2007 gets loaded instead of what you had bundled. Or worse, a dependency on the system is older than what's in your bundle so the application can't start because Gemfile.lock expects a certain version of said dependency.

    All this is avoided by making sure that you use bundler properly. Our configuration will use Bundler to launch applications when there's a Gemfile and a Gemfile.lock present, thus generally avoiding such issues as described here.

  • Avatar
    Petteri Räty

    J. Austin what you are saying about loading old versions loading is probably true on Engine Yard. However on development systems where system gems and bundler gems are always in the path you will most likely end up with newer versions instead (rubygems loads the latest version if not restricted) because of running bundler update in other projects or gem update system wide.

  • Avatar
    Justin Turner Arthur

    Thanks for the quick followup! I think I was confused, seeing those instructions in the context of customization. Looking back, step 2 (To start Unicorn in Bundler) is also a recommendation if using Engine Yard's out-of-the-box Unicorn deployment option.

  • Avatar
    Jenkins CI

    To confirm EY is loading the bundled version of Unicorn, would ps aux | grep unicorn then display 'bundle exec unicorn'? If so, it doesn't appear to be applying bundle exec for unicorn, with following the example on step 2 (adding unicorn to Gemfile).

     

    Any ideas on further tweaks? 

  • Avatar
    J. Austin Hughey

    Engine Yard uses a monit configuration script to start Unicorn, which calls a shell script that we've written especially for this. That shell script checks for the existence of a Gemfile, Bundler and bundled gems, and if it finds them, launches the version of Unicorn under the /data/appname/shared/bundled_gems directory. It's not a straight "bundle exec", but modifies $PATH in the same way, so ps would not necessarily show the "bundle exec" prefix, even though it's using the bundled version.

  • Avatar
    Jenkins CI

    Great thanks J.Austin, I noticed the Bundler.exec checking method in the monit script. Cheers.

  • Avatar
    Michael Reinsch

    Do you also have some sample code how to do that with chef? Or otherwise one will have to apply this to all servers, right?

  • Avatar
    Paul Tingle

    Hi Michael, To achieve this you would create a custom Chef recipe, putting something along the lines of the below (assuming you are only running one app) in your recipe/default.rb file:

     

    #Set your application name here
    appname = "_appname_"

    service "unicorn_#{appname}" do
    supports :restart => true
    end
    template "/data/#{appname}/shared/config/env.custom" do
    source "env.custom.erb"
    owner node[:owner_name]
    group node[:owner_name]
    mode 0644
    backup 0
    variables({
    :appname => appname
    })
    notifies :restart, resources(:service => "unicorn_#{appname}")
    end
    remote_file "/data/#{appname}/shared/config/custom_unicorn.rb" do
    source "custom_unicorn.rb"
    owner node[:owner_name]
    group node[:owner_name]
    mode 0644
    backup 0
    notifies :restart, resources(:service => "unicorn_#{appname}")
    end

     

    You would then need to create a templates/default/env.custom.erb file containing:

     

    UNICORN_CONF="/data/<%= @appname %>/shared/config/custom_unicorn.rb"

     

    Also you would need to create a files/default/custom.unicorn.rb that combined the standard Unicorn configuration with your own configuration additions. To do this you would want to copy the contents of the existing unicorn.rb config file from your application into your custom.unicorn.rb and the append your custom config to it. You can retrieve the contents of your current unicorn.rb using the following command from the command line on your local machine:

     

    ey ssh -e _environment_ "cat /data/_appname_/shared/config/unicorn.rb"

     

    One caveat is that if the contents of the unicorn.rb file were ever to be updated by ourselves, you would need to reflect these changes in the custom.unicorn.rb file.

  • Avatar
    Yves-Eric Martin

    There is now an "env_vars" recipe in the official ey-cloud-recipes cookbook.

    If you have customized manually your env.custom file, beware that this recipe will overwrite it.

  • Avatar
    Pat Leamon

    We tried this chef recipe, unfortunately we get this error when triggering the restart:

    ERROR: This script must be run as a user, not as root.

     

    We've resorted to manually invoking /etc/init.d/unicorn_appname restart, but this means it happens every time we apply recipes.

     

  • Avatar
    Ralph Bankston

    Hey Pat, If you could open a ticket for that we can take a look at it for you.

  • Avatar
    Jacob Ford

    I'm having a problem using this chef recipe.  The recipe applies fine, custom_unicorn.rb is there, the custom.env file contains the path to custom_unicorn.rb, yet unicorn still uses the standard unicorn.rb file.  Anybody run into the same problem?

  • Avatar
    Daniel Valfre

    Hi Jacob, would you mind opening a ticket so we can look into the issue?  Thanks!

Please sign in to leave a comment.

Powered by Zendesk