Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Dress to impress / Our minimalistic server configuration tool
Ruby
branch: master

This branch is 2 commits ahead, 5 commits behind assaf:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
bin
example
lib
vendor
.gitignore
CHANGELOG
README.rdoc
Rakefile
necktie.gemspec

README.rdoc

Minimalistic server configuration tool

Necktie is tool for running configuration tasks: setting up new servers and upgrading production servers. You can use it to manage services, mount volumes, change configuration, manage cronjobs, etc.

To install Necktie:

$ gem install necktie --source http://gemcutter.org

To use Necktie:

  1. Write a Necktie file with configurtaion tasks

  2. Include any support files: config, scripts, binaries, etc

  3. git push && cap necktie

Introduction to Necktie: blog.labnotes.org/2009/11/04/necktie-dress-to-impress/

Tasking

Necktie is based on Rake, so if you know Rake you already know most of Necktie. This document will teach you the rest.

At the base of your Necktie project there's a file called Necktie (or necktie, or necktie.rb), with a list of tasks. For example:

file "/var/myapp" do
  append "/etc/fstab", "/mnt/myapp /var/myapp none bind\n" unless read("/etc/fstab")["/mnt/myapp"]
  mkdir_p "/var/myapp/"
  sh "mount /var/myapp"
end

desc "Install/update ruby gems"
task :rubygems do
  FileList["gems/*.gem"].each do |gem|
    install_gem gem
  end
  sh "gem clean"
end

desc "Setup and start Nginx"
task :nginx do
  rm_rf "/etc/nginx/sites-enabled/*"
  cp "etc/nginx/unicorn.conf", "/etc/nginx/sites-available/"
  ln_sf "/etc/nginx/sites-available/unicorn.conf", "/etc/nginx/sites-enabled/"
  services.start "nginx"
end

desc "Setup and start Unicorn"
task :unicorn=>[:rubygems, "/var/myapp"] do
  cp "etc/init.d/unicorn", "/etc/init.d/"
  chmod 0750, "/etc/init.d/unicorn"
end

desc "Perform all tasks for the role app"
task :app=>["/var/myapp", :nginx, :unicorn]

When you run the app task, it runs the tasks that setup the application directory, install gems, configure Nginx and Unicorn. When it's done, you're ready to deploy.

Necktie deals with initial configuration, and also ongoing maintenance. Say you change a configuration file, or add another Gem to the gems directory. Push these changes into your Git repository and run Necktime again. That simple.

Note: In the example above, the nginx and unicorn tasks run each time, you can use them to push out new configurations. In contrast, the /var/myapp file task only runs once, before that directory exists.

cap necktie

I use Capistrano to setup new instances and upgrade existing ones.

To use the Necktie task, set the necktie_url variable to the URL of your Necktie repository, and require necktie/capistrano. For example:

require "necktie/capistrano"
set :necktie_url, "git@example.com:mysetup"

Setting up a new EC2 instance:

cap necktie ROLES=app HOSTS=ec2-75-101-239-12.compute-1.amazonaws.com

Upgrading running instances with new configuration:

git push && cap necktie

Feel the rush

Necktie includes Rush, so you can write tasks like this:

task :memcached do
  unless processes.find { |p| p.cmdline[/memcached\s.*-l\s0.0.0.0/] }
    box["/etc/memcached.conf"].replace_contents! /^-l 127.0.0.1/, "-l 0.0.0.0"
    services.start "memcached"
  end
end

You can learn more about Rush here: rush.heroku.com

Of course, there's also FileUtils, system and sh (courtesy of Rake), so you can also:

# Update whenever we have a newer config file.
file "/etc/nginx/nginx.conf"=>"etc/nginx.conf" do
  cp "etc/nginx.conf", "/etc/nginx/nginx.conf"
  sh "service nginx restart"
end

The current directory (Dir.pwd and launch_dir) is the root directory of your Necktie repository. You can depend on relative paths when accessing files in your Necktie repository.

Role play

If you have different setups, split them into roles and give each role its own main task. Have that main task depend on all the specific setup tasks for this role. For example:

task :app=>[:rubygems, :nginx, :unicorn, "/var/myapp"]
task :db=>[:mount, :master, :backup]

You can then run Necktie with a list of roles. I recommend using the same roles with Necktie and Capistrano, that way you can:

cap necktie ROLES=app,db

This usage will pass the role names as task names to the necktie command.

If you have only one role, or work frequently with a given role, you can define the default task instead of setting ROLES each time. In your Necktie file add:

task :default=>:app

You may also want to take advantage of different environments, customizing your setup differently between production, staging, etc.

Check the example directory for ideas on how to split large configurations into smaller files and tasks.

Note: As with Rake, command line arguments are either options (see necktie -H), task names (executed in order), or name=value pairs that set environment variables (e.g. RAILS_ENV=production).

gem install

You can use install_gem in one of two ways. You can pass it a gem name and version requirement. For example:

install_gem "unicorn", "~= 0.93"

You can store the gem file in your Necktie repository and install it from there:

install_gem "gems/unicorn-0.93.3.gem"

I prefer the later, not depending on the Gem servers being online when I decide to upgrade.

Since install_gem will only install the same gem/version once, a run-always rubygems.rb task is all you need:

task :rubygems do
  Dir["gems/*.gem"].each do |gem|
    install_gem gem
  end
end

One on one

You can also run Necktie from the command line directly on the server you're configuring. The first time you run Necktie, it clones the Git repository into the ~/.necktie directory. You'll need to give it the Git URL, like this:

necktie --source git@example.com:mysetup app

Subsequent runs use that repository. You can launch the necktie command from anywhere, it will always switch to the ~/.necktie directory, run the tasks and switch back to the previous working directory.

If you want to pull changes from the Git repository, use the -U option:

necktie -U app

If you have read/write access to the Git repository you use that to tweak and add new tasks, and test them out before using your setup in production.

License

Necktie, copyright (C) 2009 Assaf Arkin, released under the “Use for good, not evil” license (www.json.org/license.html)

Includes Rake, created by Jim Weirich and released under the MIT license rake.rubyforge.org/ github.com/jimweirich/rake

Includes Rush, created by Adam Wiggins and released under the MIT License rush.heroku.com github.com/adamwiggins/rush

Includes Session, created by Ara T. Howard and released under the Ruby License raa.ruby-lang.org/project/session www.codeforpeople.com/lib/ruby/session

Atomic file write adapted from Rails.

ERB task adapted from Luke Bayes gist.github.com/215270.

Developed for managing EC2 instances for apartly.com

Something went wrong with that request. Please try again.