necktie
necktie copied to clipboard
NO LONGER MAINTAINED
= 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.
http://19.media.tumblr.com/tumblr_kspcaa4Djr1qzo4cfo1_250.jpg
To install Necktie:
$ gem install necktie --source http://gemcutter.org
To use Necktie:
- Write a Necktie file with configurtaion tasks
- Include any support files: config, scripts, binaries, etc
- git push && cap necktie
Introduction to Necktie: http://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.
You can store your Necktie files in a separate repository, or same repository as your application but in a separate branch.
If using a separate repository, set the variable necktie_url to the URL of the Necktie repository. You can also set necktie_branch to particular branch name, the default is master.
For example:
require "necktie/capistrano" set :necktie_url, "[email protected]:mysetup"
If using the same repository and separate branch, do not set necktie_url. You can set necktie_branch to a particular branch name, the default in this case is necktie. You still need to require "necktie/capistrano".
To create a new empty branch for Necktie that will live in the same repository as your application (note: make sure to commit all changes first, or you'll lose them):
$ git symbolic-ref HEAD refs/heads/necktie $ rm .git/index $ git clean -fdx $ echo "# My Necktie file" > Necktie $ git add . $ git commit -a -m "First commit" $ git push origin necktie
Rather than switching back and forth, you can clone this repository within your application's working directory:
$ cd myapp $ git clone -b necktie git:myapp.git .necktie $ ls necktie
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: http://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 [email protected]: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 (http://www.json.org/license.html)
Includes Rake, created by Jim Weirich and released under the MIT license http://rake.rubyforge.org/ http://github.com/jimweirich/rake
Includes Rush, created by Adam Wiggins and released under the MIT License http://rush.heroku.com http://github.com/adamwiggins/rush
Includes Session, created by Ara T. Howard and released under the Ruby License http://raa.ruby-lang.org/project/session http://www.codeforpeople.com/lib/ruby/session
Atomic file write adapted from Rails.
ERB task adapted from Luke Bayes http://gist.github.com/215270.
Developed for managing EC2 instances for http://apartly.com