Last active
August 29, 2015 14:02
Install an Elasticsearch/Redis/Nginx/Rails/Ruby/Sinatra stack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Clones, configures and launches a Ruby web application under common Nginx | |
# | |
# Usage | |
# ----- | |
# | |
# $ export HOST=user@example.com | |
# $ export SSH_KEY=~/.ssh/yourkey.pem | |
# | |
# $ scp -i $SSH_KEY install-app.rb $HOST:/tmp | |
# | |
# $ time ssh -t -i $SSH_KEY $HOST "sudo NAME=music PORT=3000 REPO=https://karmiq@bitbucket.org/karmiq/music.git ENV=development chef-apply /tmp/install-app.rb" | |
# | |
config = {} | |
config[:name] = ENV['NAME'] | |
config[:port] = ENV['PORT'] | |
config[:repo] = ENV['REPO'] | |
config[:env] = ENV.fetch('ENV', 'development') | |
STDERR.puts '', " CONFIGURATION ".center(80, '-') | |
[ :name, :port, :repo, :env ].each do |var| | |
STDERR.puts "#{var}: ".capitalize.ljust(15) + "#{config[var]}" | |
end | |
STDERR.puts '-'*80, '', '' | |
[ :name, :port, :repo, :env ].each do |var| | |
Chef::Log.fatal "Undefined configuration for: #{var}" unless config[var] | |
end | |
user = 'application' | |
path = '/usr/local/var/applications' | |
app_start_command = <<-COMMAND | |
cd #{path}/#{config[:name]} && \ | |
RAILS_RELATIVE_URL_ROOT=/#{config[:name]} bundle exec thin \ | |
--port #{config[:port]} \ | |
--chdir #{path}/#{config[:name]} \ | |
--rackup #{path}/#{config[:name]}/config.ru \ | |
--prefix /#{config[:name]} \ | |
--environment #{config[:env]} \ | |
--pid #{path}/#{config[:name]}/tmp/#{config[:name]}.pid \ | |
--user application \ | |
--group applications \ | |
--tag #{config[:name]} \ | |
--daemonize \ | |
start | |
COMMAND | |
user "#{user}" do | |
shell "/bin/bash" | |
home "#{path}" | |
comment "Ruby Applications" | |
end | |
group "applications" do | |
members "#{user}" | |
end | |
directory "#{path}/" do | |
owner "#{user}" | |
group "applications" | |
recursive true | |
end | |
git "#{path}/#{config[:name]}" do | |
repository config[:repo] | |
user "#{user}" | |
group "applications" | |
action :sync | |
end | |
directory "#{path}/#{config[:name]}/tmp" do | |
owner "#{user}" | |
group "applications" | |
end | |
directory "#{path}/#{config[:name]}/log" do | |
owner "#{user}" | |
group "applications" | |
end | |
bash "repair permissions" do | |
code "chown -R #{user}:applications #{path}" | |
end | |
file "/etc/init.d/app-#{config[:name]}" do | |
content "#{app_start_command}" | |
owner "#{user}" | |
group "applications" | |
mode "0755" | |
end | |
bash "install Bundler" do | |
code "gem install bundler" | |
not_if "gem list | grep bundler" | |
end | |
bash "install application Rubygems" do | |
code "sudo su - #{user} -c 'BUNDLE_GEMFILE=#{path}/#{config[:name]}/Gemfile bundle install'" | |
end | |
bash "start the application immediately" do | |
code "bash /etc/init.d/app-#{config[:name]}" | |
not_if "ps aux | grep -v grep | grep #{config[:name]}" | |
end | |
ruby_block "add Nginx 'location' directive for #{config[:name]}" do | |
@file = ::File.new("/etc/nginx/conf.d/applications.conf") | |
@content = @file.read | |
block do | |
tempfile = ::Tempfile.new('applications.conf') | |
new_content = @content.gsub(/server {([\w\W]+)?}/i) do |match| | |
"server {" + $1 + " location /#{config[:name]} {\n proxy_pass http://localhost:#{config[:port]};\n }\n" + "}\n" | |
end.to_s | |
tempfile.write new_content | |
diff = Chef::Util::Diff.new.udiff @file.path, tempfile.path | |
Chef::Log.debug diff | |
FileUtils.mv tempfile.path, @file.path | |
end | |
notifies :run, "execute[nginx-reload]" | |
not_if { @content.include? "location /#{config[:name]}" } | |
end | |
execute "monit-reload" do | |
command "service monit reload" | |
action :nothing | |
end | |
execute "nginx-reload" do | |
command "service nginx reload" | |
action :nothing | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Install a basic Elasticsearch/Ruby/Rails/Nginx/etc stack to a server | |
# | |
# First, install Chef: | |
# | |
# $ export HOST=user@example.com | |
# $ export SSH_KEY=~/.ssh/yourkey.pem | |
# | |
# $ ssh -i $SSH_KEY $HOST "sudo apt-get update" | |
# $ ssh -i $SSH_KEY $HOST "curl -# -L http://www.opscode.com/chef/install.sh | sudo bash -s --" | |
# | |
# Then, upload and run the script: | |
# | |
# $ scp -i $SSH_KEY install-base.rb $HOST:/tmp | |
# $ time ssh -t -i $SSH_KEY $HOST "sudo chef-apply /tmp/install-base.rb" | |
# | |
STDOUT.sync = true | |
STDERR.sync = true | |
# ----- Packages and Tools -- | |
bash("apt update") { code "apt-get update" } | |
%w| build-essential | |
make | |
bison | |
zlib1g-dev | |
libopenssl-ruby1.9.1 | |
libcurl4-openssl-dev | |
libssl-dev | |
libyaml-dev | |
libxml2-dev libxslt1-dev | |
libreadline-dev | |
libncurses5-dev | |
file | |
sqlite3 libsqlite3-dev | |
ruby1.9.3 | |
curl | |
vim | |
git | |
htop |.each { |name| package name } | |
# ----- Elasticsearch ------- | |
package "openjdk-7-jre-headless" | |
remote_file "/tmp/elasticsearch-1.2.1.deb" do | |
source "https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.2.1.deb" | |
checksum "60ae2764782369aea2428e634eda092830832cd9" | |
action :create_if_missing | |
end | |
dpkg_package "elasticsearch-1.2.1.deb" do | |
package_name "elasticsearch" | |
source "/tmp/elasticsearch-1.2.1.deb" | |
end | |
bash "set ES_HEAP_SIZE" do | |
code "echo 'ES_HEAP_SIZE=256m' >> /etc/default/elasticsearch" | |
not_if "grep '^ES_HEAP_SIZE=256m' /etc/default/elasticsearch" | |
end | |
bash "configure Elasticsearch" do | |
code "echo 'cluster.name: ruby-elasticsearch' >> /etc/elasticsearch/elasticsearch.yml" | |
not_if "grep '^cluster.name: ruby-elasticsearch' /etc/elasticsearch/elasticsearch.yml" | |
end | |
service "elasticsearch" do | |
action [ :enable, :start ] | |
end | |
# ----- Redis --------------- | |
package "redis-server" | |
# ----- Nginx --------------- | |
package "nginx" | |
file "/etc/nginx/conf.d/applications.conf" do | |
content <<-CONTENT.gsub(/^ /, '') | |
server { | |
listen 80; | |
location / { | |
root /usr/local/var/applications; | |
} | |
} | |
CONTENT | |
notifies :run, "execute[nginx-reload]" | |
end | |
# ----- Node.js (for Rails assets) | |
package "nodejs" | |
# ----- The Application ----- | |
bash "install Bundler" do | |
code "gem install bundler" | |
not_if "gem list | grep bundler" | |
end | |
# ----- Monit ----- | |
package 'monit' | |
file "/etc/monit/monitrc" do | |
content <<-CONTENT.gsub(/^ /, '') | |
set daemon 60 | |
set logfile /var/log/monit.log | |
set httpd port 2812 and | |
use address localhost | |
allow localhost | |
check process redis with pidfile /var/run/redis/redis-server.pid | |
start program = "/usr/sbin/service redis-server start" with timeout 60 seconds | |
stop program = "/usr/sbin/service redis-server stop" | |
if cpu > 90% for 15 cycles then alert | |
if totalmem > 90% for 15 cycles then alert | |
group redis | |
check process elasticsearch with pidfile /var/run/elasticsearch.pid | |
start program = "/usr/sbin/service elasticsearch start" with timeout 60 seconds | |
stop program = "/usr/sbin/service elasticsearch stop" | |
if cpu > 90% for 15 cycles then alert | |
if totalmem > 90% for 15 cycles then alert | |
group elasticsearch | |
check process nginx with pidfile /run/nginx.pid | |
start program = "/usr/sbin/service nginx start" with timeout 60 seconds | |
stop program = "/usr/sbin/service nginx stop" | |
if cpu > 90% for 15 cycles then alert | |
if totalmem > 90% for 15 cycles then alert | |
group nginx | |
CONTENT | |
notifies :run, "execute[monit-reload]" | |
end | |
execute "monit-reload" do | |
command "service monit reload" | |
action :nothing | |
end | |
execute "nginx-reload" do | |
command "service nginx reload" | |
action :nothing | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment