Skip to content
Permalink
Browse files

Gemifying the original files from Railscast 337 as a starting point

  • Loading branch information...
cwsaylor committed Apr 2, 2012
0 parents commit 6595375b9f24a7e90f0efd342558456dc49fd7b4
@@ -0,0 +1,18 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
.DS_Store
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in cap_bootstrap.gemspec
gemspec
22 LICENSE
@@ -0,0 +1,22 @@
Copyright (c) 2012 Chris Saylor

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,99 @@
# Cap Bootstrap

Capistrano tasks for deploying Rails applications using Ubuntu 10.04, rbenv, nginx, Unicorn and PostgreSQL. Based on the excellent Railscasts by Ryan Bates, with permission of course. If you are new to Capistrano or setting up a VPS, I highly recommend subscribing to his pro screencasts and watching the following:

* [Deploying to a VPS](http://railscasts.com/episodes/335-deploying-to-a-vps) (Pro)
* [Capistrano Tasks](http://railscasts.com/episodes/133-capistrano-tasks-revised) (Free)
* [Capistrano Recipes](http://railscasts.com/episodes/337-capistrano-recipes) (Pro)

I am not affiliated with Railscasts, I'm just a fan.

## Requirements

* Capistrano
* Fresh Ubuntu 10.04 or 11.10 install

## Installation

Add these lines to your application's Gemfile:

gem 'capistrano'
gem 'cap_bootstrap'

And then execute:

$ bundle

## Usage

Setup a new Ubuntu 10.04 slice. Add a user called deployer with sudo privileges.

In your project, run the following:

capify .

Overwrite the default deploy.rb with the following:

require "bundler/capistrano"
require "cap_bootstrap/capistrano"
server "99.99.99.99", :web, :app, :db, primary: true
set :user, "deployer"
set :application, "blog"
set :deploy_to, "/home/#{user}/apps/#{application}"
set :deploy_via, :remote_cache
set :use_sudo, false
set :scm, "git"
set :repository, "git@github.com:GITHUB_USER/#{application}.git"
set :branch, "master"
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
after "deploy", "deploy:cleanup" # keep only the last 5 releases

Customize the server IP address, the application name, and the repository.

Back in your project:

cap deploy:install
cap deploy:setup
cap deploy:cold

## Advanced Options

### PostgreSQL

set :postgresql_host, "localhost"
set :postgresql_user { application }
set :postgresql_database { "#{application}_production" }

### Ruby

set :ruby_version, "1.9.3-p125"
set :rbenv_bootstrap, "bootstrap-ubuntu-10-04" # Or bootstrap-ubuntu-11-10

### Unicorn

set :unicorn_user { user }
set :unicorn_pid { "#{current_path}/tmp/pids/unicorn.pid" }
set :unicorn_config { "#{shared_path}/config/unicorn.rb" }
set :unicorn_log { "#{shared_path}/log/unicorn.log" }
set :unicorn_workers, 2

## Future Plans

Version 0.1 uses Ryan's recipes pulled directly from Railscast episode #337 Capistrano Recipes. You will always be able to access this version
with tag v0.1. Future versions will incorporate optional installs such as MySQL, Apache, Phusion Passenger and additional server config such as setting a hostname and installing a firewall.

## Alternatives

* [Chef](http://www.opscode.com/chef/)
* [Puppet](http://puppetlabs.com/)
* [deprec](http://deprec.org/)

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

@@ -0,0 +1,2 @@
#!/usr/bin/env rake
require "bundler/gem_tasks"
@@ -0,0 +1,17 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/cap_bootstrap/version', __FILE__)

Gem::Specification.new do |gem|
gem.authors = ["Christopher Saylor"]
gem.email = ["chris@justhack.com"]
gem.description = %q{Capistrano tasks for deploying Rails applications using Ubuntu 10.04, rbenv, nginx, Unicorn and PostgreSQL.}
gem.summary = %q{Capistrano tasks for deploying Rails applications using Ubuntu 10.04, rbenv, nginx, Unicorn and PostgreSQL.}
gem.homepage = "http://github.com/cwsaylor/cap_bootstrap"

gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "cap_bootstrap"
gem.require_paths = ["lib"]
gem.version = CapBootstrap::VERSION
end
@@ -0,0 +1,5 @@
require "cap_bootstrap/version"

module CapBootstrap
# Your code goes here...
end
@@ -0,0 +1,7 @@
require 'cap_bootstrap/recipes/base'
require 'cap_bootstrap/recipes/check'
require 'cap_bootstrap/recipes/nginx'
require 'cap_bootstrap/recipes/nodejs'
require 'cap_bootstrap/recipes/postgresql'
require 'cap_bootstrap/recipes/rbenv'
require 'cap_bootstrap/recipes/unicorn'
@@ -0,0 +1,18 @@
Capistrano::Configuration.instance(:must_exist).load do
def template(from, to)
erb = File.read(File.expand_path("../templates/#{from}", __FILE__))
put ERB.new(erb).result(binding), to
end

def set_default(name, *args, &block)
set(name, *args, &block) unless exists?(name)
end

namespace :deploy do
desc "Install everything onto the server"
task :install do
run "#{sudo} apt-get -y update"
run "#{sudo} apt-get -y install python-software-properties"
end
end
end
@@ -0,0 +1,15 @@
Capistrano::Configuration.instance(:must_exist).load do
namespace :check do
desc "Make sure local git is in sync with remote."
task :revision, roles: :web do
unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
puts "WARNING: HEAD is not the same as origin/#{branch}"
puts "Run `git push` to sync changes."
exit
end
end
before "deploy", "check:revision"
before "deploy:migrations", "check:revision"
before "deploy:cold", "check:revision"
end
end
@@ -0,0 +1,27 @@
Capistrano::Configuration.instance(:must_exist).load do
namespace :nginx do
desc "Install latest stable release of nginx"
task :install, roles: :web do
run "#{sudo} add-apt-repository ppa:nginx/stable"
run "#{sudo} apt-get -y update"
run "#{sudo} apt-get -y install nginx"
end
after "deploy:install", "nginx:install"

desc "Setup nginx configuration for this application"
task :setup, roles: :web do
template "nginx_unicorn.erb", "/tmp/nginx_conf"
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-enabled/#{application}"
run "#{sudo} rm -f /etc/nginx/sites-enabled/default"
restart
end
after "deploy:setup", "nginx:setup"

%w[start stop restart].each do |command|
desc "#{command} nginx"
task command, roles: :web do
run "#{sudo} service nginx #{command}"
end
end
end
end
@@ -0,0 +1,11 @@
Capistrano::Configuration.instance(:must_exist).load do
namespace :nodejs do
desc "Install the latest relase of Node.js"
task :install, roles: :app do
run "#{sudo} add-apt-repository ppa:chris-lea/node.js"
run "#{sudo} apt-get -y update"
run "#{sudo} apt-get -y install nodejs"
end
after "deploy:install", "nodejs:install"
end
end
@@ -0,0 +1,36 @@
Capistrano::Configuration.instance(:must_exist).load do
set_default(:postgresql_host, "localhost")
set_default(:postgresql_user) { application }
set_default(:postgresql_password) { Capistrano::CLI.password_prompt "PostgreSQL Password: " }
set_default(:postgresql_database) { "#{application}_production" }

namespace :postgresql do
desc "Install the latest stable release of PostgreSQL."
task :install, roles: :db, only: {primary: true} do
run "#{sudo} add-apt-repository ppa:pitti/postgresql"
run "#{sudo} apt-get -y update"
run "#{sudo} apt-get -y install postgresql libpq-dev"
end
after "deploy:install", "postgresql:install"

desc "Create a database for this application."
task :create_database, roles: :db, only: {primary: true} do
run %Q{#{sudo} -u postgres psql -c "create user #{postgresql_user} with password '#{postgresql_password}';"}
run %Q{#{sudo} -u postgres psql -c "create database #{postgresql_database} owner #{postgresql_user};"}
end
after "deploy:setup", "postgresql:create_database"

desc "Generate the database.yml configuration file."
task :setup, roles: :app do
run "mkdir -p #{shared_path}/config"
template "postgresql.yml.erb", "#{shared_path}/config/database.yml"
end
after "deploy:setup", "postgresql:setup"

desc "Symlink the database.yml file into latest release"
task :symlink, roles: :app do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
after "deploy:finalize_update", "postgresql:symlink"
end
end
@@ -0,0 +1,29 @@
Capistrano::Configuration.instance(:must_exist).load do
set_default :ruby_version, "1.9.3-p125"
set_default :rbenv_bootstrap, "bootstrap-ubuntu-10-04"

namespace :rbenv do
desc "Install rbenv, Ruby, and the Bundler gem"
task :install, roles: :app do
run "#{sudo} apt-get -y install curl git-core"
run "curl -L https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash"
bashrc = <<-BASHRC
if [ -d $HOME/.rbenv ]; then
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
fi
BASHRC
put bashrc, "/tmp/rbenvrc"
run "cat /tmp/rbenvrc ~/.bashrc > ~/.bashrc.tmp"
run "mv ~/.bashrc.tmp ~/.bashrc"
run %q{export PATH="$HOME/.rbenv/bin:$PATH"}
run %q{eval "$(rbenv init -)"}
run "rbenv #{rbenv_bootstrap}"
run "rbenv install #{ruby_version}"
run "rbenv global #{ruby_version}"
run "gem install bundler --no-ri --no-rdoc"
run "rbenv rehash"
end
after "deploy:install", "rbenv:install"
end
end
@@ -0,0 +1,27 @@
upstream unicorn {
server unix:/tmp/unicorn.<%= application %>.sock fail_timeout=0;
}

server {
listen 80 default deferred;
# server_name example.com;
root <%= current_path %>/public;

location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}

try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}

error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
@@ -0,0 +1,8 @@
production:
adapter: postgresql
encoding: unicode
database: <%= postgresql_database %>
pool: 5
username: <%= postgresql_user %>
password: <%= postgresql_password %>
host: <%= postgresql_host %>
@@ -0,0 +1,8 @@
working_directory "<%= current_path %>"
pid "<%= unicorn_pid %>"
stderr_path "<%= unicorn_log %>"
stdout_path "<%= unicorn_log %>"

listen "/tmp/unicorn.<%= application %>.sock"
worker_processes <%= unicorn_workers %>
timeout 30
Oops, something went wrong.

0 comments on commit 6595375

Please sign in to comment.
You can’t perform that action at this time.