cookbook 'unicorn-ng', '~> 2.0.1'
unicorn-ng (10) Versions 2.0.1 Follow2
Installs/Configures unicorn
cookbook 'unicorn-ng', '~> 2.0.1', :supermarket
knife supermarket install unicorn-ng
knife supermarket download unicorn-ng
unicorn-ng Cookbook
Manage your unicorn application server with this cookbook.
This cookbook provides a decent initscript for Debian/Ubuntu, as well as takes care of the unicorn configuration.
Features
- Provides a decent initscript for Debian/Ubuntu
- Automatically takes care of ActiveRecord connections (if ActiveRecord is used)
- Hightly configurable for your needs
- Use either a system-wide installed unicorn, or one that gets deployed with your application
Requirements
An installed unicorn. Alterantively you can use the install recipe to install it using rubygems.
Furthermore you need to add the following line to your metadata.rb
depends 'unicorn-ng'
Attributes
Packages
To install unicorn, rubygems is required. The cookbook tries to figure out automatically which packages are required depending on your current OS.
It is possible to override the automatic settings and specify them manually, though
node['unicorn-ng']['packages'] = %w(rubygems)
Configuration
Everything in your unicorn.rb can be maintained using attributes.
Consider using the provides LWRPs (see below)
Most importantly, you need to specify the path to your unicorn.rb.
If this is not specified, the default recipe will do nothing.
You can also specify a working directory, if needed
node['unicorn-ng']['config']['config_file'] = '/var/www/examples.com/config/unicorn.rb' node['unicorn-ng']['config']['working_directory'] = '/var/www/examples.com'
This section describes the supported attributes, as well as their default settings.
node['unicorn-ng']['config']['worker_processes'] = 1 node['unicorn-ng']['config']['listen'] = 8080 node['unicorn-ng']['config']['backlog'] = nil node['unicorn-ng']['config']['pid'] = 'tmp/pids/unicorn.pid' node['unicorn-ng']['config']['timeout'] = 60 node['unicorn-ng']['config']['stderr_path'] = 'log/unicorn.stderr.log' node['unicorn-ng']['config']['stdout_path'] = 'log/unicorn.stdout.log' node['unicorn-ng']['config']['preload_app'] = true # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and # immediately start loading up a new version of itself (loaded with a new # version of our app). When this new Unicorn is completely loaded # it will begin spawning workers. The first worker spawned will check to # see if an .oldbin pidfile exists. If so, this means we've just booted up # a new Unicorn and need to tell the old one that it can now die. To do so # we send it a QUIT. # # Using this method we get 0 downtime deploys. # # Stolen from: https://github.com/blog/517-unicorn node['unicorn-ng']['config']['before_fork'] = <<-EOS old_pid = '#{node['unicorn-ng']['config']['pid']}.oldbin' if File.exists?(old_pid) and server.pid != old_pid begin Process.kill('QUIT', File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH # someone else did our job for us end end if defined?(ActiveRecord::Base) ActiveRecord::Base.connection_handler.clear_all_connections! end EOS node['unicorn-ng']['config']['after_fork'] = <<-EOS if defined?(ActiveRecord::Base) ActiveRecord::Base.connection_handler.verify_active_connections! end EOS
It's also possible to add arbitrary commands to the top of unicorn.rb
in case you need something
like a special require
statement.
node['unicorn-ng']['config']['prescript'] = <<-EOS # Load the GELF logging extension require 'gelf' logger ::GELF::Logger.new('graylog', 1234, 'LAN', {facility: 'unicorn'}) EOS
Furthermore, you can define more advanced settings, if needed (ignored when using systemd)
node['unicorn-ng']['config']['owner'] = 'root' node['unicorn-ng']['config']['group'] = 'root' node['unicorn-ng']['config']['mode'] = 00644 node['unicorn-ng']['config']['cookbook'] = 'unicorn-ng' node['unicorn-ng']['config']['source'] = 'unicorn.rb.erb' node['unicorn-ng']['config']['variables'] = {}
Service
This cookbook can set up unicorn so it gets properly started at boot time.
Analogue to the configuration, you need to specify the path to your rails application.
If this is not specified, the default recipe will do nothing.
node['unicorn-ng']['service']['rails_root'] = '/var/www/example.com'
The following attributes will be set automatically relative to the rails_root, if not specified.
node['unicorn-ng']['service']['config'] = nil node['unicorn-ng']['service']['bundle_gemfile'] = nil node['unicorn-ng']['service']['pidfile'] = nil
If you need a different bundler (e.g. a wrapper from rvm), you can specify it here
node['unicorn-ng']['service']['bundle'] = '/usr/local/bin/bundle'
It's also possible (since 0.2.0) to specify a wrapper (like chruby-exec) (disabled by default)
node['unicorn-ng']['service']['wrapper'] = '/usr/local/bin/chruby-exec' node['unicorn-ng']['service']['wrapper_opts'] = "#{my_ruby_string} --" node['unicorn-ng']['service']['bundle'] = 'bundle'
In the same way, you can set your custom GEM_HOME
path:
node['unicorn-ng']['service']['gem_home'] = '/usr/local/ruby/gems'
Since version 1.2.1
, you can specify the --chdir
flag for start-stop-daemon
, which results in
a chdir before the app starts
node['unicorn-ng']['service']['chdir'] = '/home/myapp'
The RAILS_ENV. Set this to 'production' in your production environment
node['unicorn-ng']['service']['environment'] = 'development'
The user unicorn runs at. NOTE: THIS SHOULD BE CHANGED TO AN UNPRIVILEDGED USER
node['unicorn-ng']['service']['user'] = 'root' # CHANGE ME! (e.g. 'www-data')
The locale (set by the initscript)
node['unicorn-ng']['service']['locale'] = 'en_US.UTF-8'
Use systemd (defaults to true on Ubuntu >= 15.04)
NOTE: This is recommended on machines with systemd, as it's a way cleaner solution. However, the 'status', 'add-worker' and 'remove-worker' actions are not supported on systemd. Furthermore, systemd restart
equals former full-restart
, reload
is behaving like former restart
and the former reload
was dropped.
node['unicorn-ng']['service']['systemd'] = false
Since 0.3.0, you can specify the service name. The initscript will be deployed to /etc/init.d/$SERVICENAME
, or, when systemd is used, to /etc/systemd/system/$SERVICENAME.service
Defaults to 'unicorn'
node['unicorn-ng']['service']['name'] = 'unicorn'
Additional options for the initscript (if required, ignored when using systemd)
node['unicorn-ng']['service']['owner'] = 'root' node['unicorn-ng']['service']['group'] = 'root' node['unicorn-ng']['service']['mode'] = 00755 node['unicorn-ng']['service']['cookbook'] = 'unicorn-ng' node['unicorn-ng']['service']['source'] = 'unicorn.init.erb' node['unicorn-ng']['service']['variables'] = {}
Recipes
default
Configures unicorn.rb configuration, as well as the unicorn initscript according to the attributes above.
Unless you specify at least one of the following attributes, this recipe will do nothing.
node['unicorn-ng']['config']['config_file'] # path to your unicorn.rb (will configure unicorn.rb) node['unicorn-ng']['service']['rails_root'] # path to your rails_root (will configure the unicorn service)
install
Installs bundler and unicorn using the systems "rubygems".
Consider installing a more recent environment using tools like rvm.
Provider
unicorn_ng_config
Configures unicorn.rb.
This LWRP uses the given attributes (see above) as defaults, if not specified otherwise.
Example:
unicorn_ng_config '/var/www/example.com/shared/config/unicorn.rb'
Or, a more complex setup:
unicorn_ng_config '/var/www/example.com/shared/config/unicorn.rb' do worker_processes 16 if node.chef_environment == 'production' worker_processes 6 if node.chef_environment == 'staging' worker_processes 2 if node.chef_environment == 'development' case node.chef_environment when 'production', 'staging' # We may be started by root, thus dropping privileges user 'deploy' working_directory '/var/www/example.com/current' # Listen on UNIX domain socket only # Shorter backlog for quicker failover when busy listen 'unix:tmp/sockets/unicorn.sock' backlog 1024 when 'development' listen 8080 end # Kill workers after 30 seconds on production timeout (node.chef_environment == 'production' ? 30 : 60) end
unicorn_ng_service
Deploys and configures unicorn initscript.
This LWRP uses the given attributes (see above) as defaults, if not specified otherwise.
Example:
unicorn_ng_service '/var/www/example.com/current'
In case you e.g. want to use the unicorn bundled with your configuration, you may set up a rvm wrapper for bundler
Using fnichol-rvm:
rvm_wrapper 'init' do binary 'bundle' ruby_string 'ruby-2.0.0@myapp' end
Or do it manually
rvm wrapper ruby-2.0.0@myapp init bundler
The initscript then uses this bundler to call unicorn with
bundle exec unicorn [ARGS]
Then tell the service to use your custom bundler:
unicorn_ng_service '/var/www/example.com/current' do environment node.chef_environment user 'deploy' # use a custom bundle-environment bundle '/usr/local/rvm/bin/init_bundle' end
An example with chruby-exec
unicorn_ng_service '/var/www/example.com/current' do wrapper '/usr/local/bin/chruby-exec' wrapper_opts '1.9.3-p448 --'' bundle 'bundle' environment node.chef_environment user 'deploy' end
Contributing
Contributions are very welcome!
- Fork the repository on Github
- Create a named feature branch (like
add_component_x
) - Write you change
- Write tests for your change (if applicable)
- Run the tests, ensuring they all pass
- Submit a Pull Request using Github
License and Authors
Author: Chris Aumann me@chr4.org
Contributor: Moshe Bergman bergmanm@gmail.com
License: GPLv3
Dependent cookbooks
This cookbook has no specified dependencies.
Contingent cookbooks
There are no cookbooks that are contingent upon this one.
CHANGELOG for unicorn-ng
This file is used to list changes made in each version of unicorn.
2.0.1:
- Automatically run
systemctl daemon-reload
upon changes of unicorn.service
2.0.0:
- Add systemd support. Automatically use it on recent Ubuntu machines.
See
systemd
attribute for service provider for details.
1.2.2:
- Fix some warnings for upcoming Chef-13 release
1.2.1:
- Add support to specify a working directory using the
chdir
attribute
1.1.1:
- Add
GEM_HOME
support.
1.1.0:
- Add
prescript
attribute, to inject arbitrary commands at the top ofunicorn.rb
1.0.0:
- Adapt
before_fork
andafter_fork
statements to be rails 4 compatible: See: 5c96507. It should be still working with rails 3.
0.3.0:
- Support
node['unicorn-ng']['service']['name']
attribute, to allow multiple instances - Remove
node['unicorn-ng']['service']['path']
in favor of name - Add rubocup and foodcritic checks via Travis
0.2.1:
- Make initscript independent from users login shell. This fixes a bug happening when starting the initscript with a chruby wrapper on a non-bash shell
0.2.0:
- Support wrapper and wrapper_opts
This makes the use of chruby-exec and other wrappers possible.
0.1.1:
- Use pidfile variable in unicorn.rb This fixes a bug with unicorn restart when using config provider with custom pid attribute
0.1.0:
- Initial release of unicorn-ng
Collaborator Number Metric
2.0.1 failed this metric
Failure: Cookbook has 0 collaborators. A cookbook must have at least 2 collaborators to pass this metric.
Contributing File Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a CONTRIBUTING.md file
Foodcritic Metric
2.0.1 failed this metric
FC021: Resource condition in provider may not behave as expected: unicorn-ng/providers/service.rb:28
FC066: Ensure chef_version is set in metadata: unicorn-ng/metadata.rb:1
FC069: Ensure standardized license defined in metadata: unicorn-ng/metadata.rb:1
Run with Foodcritic Version 16.3.0 with tags metadata,correctness ~FC031 ~FC045 and failure tags any
No Binaries Metric
2.0.1 passed this metric
Testing File Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a TESTING.md file
Version Tag Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must include a tag that matches this cookbook version number
2.0.1 failed this metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a CONTRIBUTING.md file
Foodcritic Metric
2.0.1 failed this metric
FC021: Resource condition in provider may not behave as expected: unicorn-ng/providers/service.rb:28
FC066: Ensure chef_version is set in metadata: unicorn-ng/metadata.rb:1
FC069: Ensure standardized license defined in metadata: unicorn-ng/metadata.rb:1
Run with Foodcritic Version 16.3.0 with tags metadata,correctness ~FC031 ~FC045 and failure tags any
No Binaries Metric
2.0.1 passed this metric
Testing File Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a TESTING.md file
Version Tag Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must include a tag that matches this cookbook version number
2.0.1 failed this metric
FC066: Ensure chef_version is set in metadata: unicorn-ng/metadata.rb:1
FC069: Ensure standardized license defined in metadata: unicorn-ng/metadata.rb:1
Run with Foodcritic Version 16.3.0 with tags metadata,correctness ~FC031 ~FC045 and failure tags any
2.0.1 passed this metric
Testing File Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must contain a TESTING.md file
Version Tag Metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must include a tag that matches this cookbook version number
2.0.1 failed this metric
2.0.1 failed this metric
Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of https://github.com/user/repo, and your repo must include a tag that matches this cookbook version number