Making Recipes
Thursday, November 21, 2013, at 06:37PM
By Eric Richardson
Screenshot of a Chef cookbook used to build ewr.is, showing a recipe that creates the directory structure for the site and installs its configuration into the nginx web server.
I brought this site out of mothballs last month by bemoaning how easy it was to fall behind on the things that we do for a living. I'm proud to say that I took my admonition to heart, and today this site is running on a newly spun-up virtual machine that is 100% built via automation.
I'm using Chef for configuration management, since that's what I use day-to-day at Emcien. My little one-server deployment gave me an excuse to try out their hosted product, as compared to the open-source server we're running.
A handful of off-the-shelf recipes do the initial setup:
- hostname: Set the server's host name based on the node name and the "ewr.is" domain.
- users::sysadmins: Create my user account from information in a data bag.
- sudo: Grant sudo rights to the proper user groups.
- ntp: Make sure we're running the NTP daemon to sync the server clock.
- nodejs: Install NodeJS from packages.
- redis::server: Install Redis server.
- percona::server: Install the Percona MySQL server.
After that, a few of my own cookbooks take over.
I put together a quick nginx_passenger cookbook to deploy NGINX and Phusion Passenger via the .deb packages that Phusion recently started building.
A lifeguard cookbook installs the lifeguard process runner that I wrote for Emcien. A
lifeguard_service
resource then offers a quick way to install new services that will restart via the Capistrano-friendlytouch tmp/restart.txt
.The cleverly-named ewr cookbook ties the two together, illustrating how this site gets configured:
include_recipe "nginx_passenger"
# -- Pre-reqs -- #
package "imagemagick"
package "libimage-exiftool-perl"
Run the nginx_passenger::default
recipe, then install two packages the site needs to run.
# -- Create a User and Directory -- #
ewr_app "ewr" do
action :create
with_cap true
ruby "1.9.1"
env({RAILS_ENV:"production"})
end
dir = "#{node.ewr.app_path}/ewr"
Use a little app
resource to create a user and home directory, install Ruby 1.9.3 (1.9.1 is the ABI version, which packages still use) and set our environment.
# -- Make asset_images directory -- #
directory "/data/ewr/asset_images" do
action :create
owner "ewr"
recursive true
end
Create the directory that we need for storing images.
# -- Install the Site File -- #
nginx_passenger_site "ewr" do
action :install
dir "#{dir}/current"
server "ewr.is"
ruby "/usr/bin/ruby1.9.1"
rails_env "production"
end
Create an NGINX site configuration file pointing to the server we created.
# -- Install Lifeguard and Tasks -- #
lifeguard_service "ewr.is Resque Pool" do
action [:enable,:start]
command "bundle exec resque-pool"
user "ewr"
dir "#{dir}/current"
service "ewr-resque"
path "#{dir}/bin"
env({RAILS_ENV:"production"})
end
Install a Lifeguard-managed Resque Pool instance, used for processing images.
The resulting code may not be useful to anyone else, but at least I don't have to be embarrassed when I log on to my own server.