Skip to content

Commit d170599

Browse files
author
Tair Assimov
committed
Add Capistrano deployment recipes and readme
1 parent cdd087a commit d170599

20 files changed

+627
-36
lines changed

.ruby-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.2.2

Capfile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
require 'capistrano/setup'
2+
require 'capistrano/deploy'
3+
require 'capistrano/rbenv'
4+
require 'capistrano/bundler'
5+
require 'capistrano/rails/assets'
6+
require 'capistrano/rails/migrations'
7+
8+
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
9+
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
10+
Dir.glob('lib/capistrano/**/*.rb').each { |r| import r }
11+

Gemfile

+6-5
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ gem 'sdoc', '~> 0.4.0', group: :doc
2626
# Use ActiveModel has_secure_password
2727
# gem 'bcrypt', '~> 3.1.7'
2828

29-
# Use Unicorn as the app server
30-
# gem 'unicorn'
31-
32-
# Use Capistrano for deployment
33-
# gem 'capistrano-rails', group: :development
29+
gem 'unicorn'
3430

3531
group :development, :test do
3632
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
3733
gem 'byebug'
34+
35+
gem 'capistrano', '~> 3.1'
36+
gem 'capistrano-rails', '~> 1.1'
37+
gem 'capistrano-rbenv', '~> 2.0'
38+
gem 'capistrano-bundler', '~> 1.1'
3839
end
3940

4041
group :development do

Gemfile.lock

+32
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,27 @@ GEM
4141
debug_inspector (>= 0.0.1)
4242
builder (3.2.2)
4343
byebug (6.0.2)
44+
capistrano (3.4.0)
45+
i18n
46+
rake (>= 10.0.0)
47+
sshkit (~> 1.3)
48+
capistrano-bundler (1.1.4)
49+
capistrano (~> 3.1)
50+
sshkit (~> 1.2)
51+
capistrano-rails (1.1.3)
52+
capistrano (~> 3.1)
53+
capistrano-bundler (~> 1.1)
54+
capistrano-rbenv (2.0.3)
55+
capistrano (~> 3.1)
56+
sshkit (~> 1.3)
4457
coffee-rails (4.1.0)
4558
coffee-script (>= 2.2.0)
4659
railties (>= 4.0.0, < 5.0)
4760
coffee-script (2.4.1)
4861
coffee-script-source
4962
execjs
5063
coffee-script-source (1.9.1.1)
64+
colorize (0.7.7)
5165
debug_inspector (0.0.2)
5266
erubis (2.7.0)
5367
execjs (2.6.0)
@@ -62,6 +76,7 @@ GEM
6276
railties (>= 4.2.0)
6377
thor (>= 0.14, < 2.0)
6478
json (1.8.3)
79+
kgio (2.9.3)
6580
loofah (2.0.3)
6681
nokogiri (>= 1.5.9)
6782
mail (2.6.3)
@@ -70,6 +85,9 @@ GEM
7085
mini_portile (0.6.2)
7186
minitest (5.8.0)
7287
multi_json (1.11.2)
88+
net-scp (1.2.1)
89+
net-ssh (>= 2.6.5)
90+
net-ssh (2.10.0)
7391
nokogiri (1.6.6.2)
7492
mini_portile (~> 0.6.0)
7593
rack (1.6.4)
@@ -99,6 +117,7 @@ GEM
99117
activesupport (= 4.2.4)
100118
rake (>= 0.8.7)
101119
thor (>= 0.18.1, < 2.0)
120+
raindrops (0.15.0)
102121
rake (10.4.2)
103122
rdoc (4.2.0)
104123
sass (3.4.18)
@@ -119,6 +138,10 @@ GEM
119138
activesupport (>= 3.0)
120139
sprockets (>= 2.8, < 4.0)
121140
sqlite3 (1.3.10)
141+
sshkit (1.7.1)
142+
colorize (>= 0.7.0)
143+
net-scp (>= 1.1.2)
144+
net-ssh (>= 2.8.0)
122145
thor (0.19.1)
123146
thread_safe (0.3.5)
124147
tilt (2.0.1)
@@ -129,6 +152,10 @@ GEM
129152
uglifier (2.7.2)
130153
execjs (>= 0.3.0)
131154
json (>= 1.8.0)
155+
unicorn (4.9.0)
156+
kgio (~> 2.6)
157+
rack
158+
raindrops (~> 0.7)
132159
web-console (2.2.1)
133160
activemodel (>= 4.0)
134161
binding_of_caller (>= 0.7.2)
@@ -140,6 +167,10 @@ PLATFORMS
140167

141168
DEPENDENCIES
142169
byebug
170+
capistrano (~> 3.1)
171+
capistrano-bundler (~> 1.1)
172+
capistrano-rails (~> 1.1)
173+
capistrano-rbenv (~> 2.0)
143174
coffee-rails (~> 4.1.0)
144175
jbuilder (~> 2.0)
145176
jquery-rails
@@ -150,6 +181,7 @@ DEPENDENCIES
150181
sqlite3
151182
turbolinks
152183
uglifier (>= 1.3.0)
184+
unicorn
153185
web-console (~> 2.0)
154186

155187
BUNDLED WITH

README.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Rails with Capistrano
2+
3+
A sample application to demonstrate deployment of Capistrano driven Rails apps in [Dockbit](https://dockbit.com). The guide below describes how to prepare a target server and also may be used as a starter kit for running Rails applications in a single server environment. It is built upon [Ubuntu 14.04](http://releases.ubuntu.com/14.04/) with the following components:
4+
5+
* [Unicorn](http://unicorn.bogomips.org/) Web server with an init script and zero-downtime configuration
6+
* [Nginx](http://nginx.org/) Proxy with a production like settings and optional SSL
7+
* [Log rotation](http://www.linuxcommand.org/man_pages/logrotate8.html) with sane defaults
8+
* [Capistrano](http://capistranorb.com/) recipes for Rails applications
9+
10+
## Preparing target server
11+
12+
### Update server info
13+
14+
Open [config/deploy/production.rb](./config/deploy/production.rb) and ```set :host_name``` to FQDN of your target server.
15+
16+
### Create deployment user
17+
18+
useradd deployer -m -s /bin/bash
19+
passwd deployer # Remember password, you'll need it later
20+
echo 'deployer ALL=NOPASSWD: ALL' >> /etc/sudoers
21+
su - deployer
22+
23+
### Install dependencies
24+
25+
sudo apt-get -y update
26+
sudo apt-get -y install nginx git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
27+
28+
### Install Javascript Runtime
29+
30+
sudo add-apt-repository -y ppa:chris-lea/node.js
31+
sudo apt-get -y update
32+
sudo apt-get -y install nodejs
33+
34+
### Install Rbenv
35+
36+
cd
37+
git clone git://github.com/sstephenson/rbenv.git .rbenv
38+
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
39+
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
40+
41+
git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
42+
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bash_profile
43+
source ~/.bash_profile
44+
45+
### Install Ruby and Bundler
46+
47+
rbenv install -v 2.2.2
48+
rbenv global 2.2.2
49+
gem install bundler --no-ri --no-rdoc
50+
rbenv rehash
51+
52+
### Set up credentials
53+
54+
Finally, you need to provide Rails secret key base as an environment variable. Run this command from within your Rails application on your machine:
55+
56+
echo "export SECRET_KEY_BASE=\"$(bundle exec rake secret)\"" | ssh deployer@FQDN_OF_YOUR_SERVER 'cat >> ~/.bash_profile'
57+
58+
You now have a target server and can proceed adding it to your deployment pipeline in Dockbit.
59+
60+

README.rdoc

-28
This file was deleted.

app/views/layouts/application.html.erb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<title>Demo</title>
4+
<title>Demo Rails Capistrano</title>
55
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
66
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
77
<%= csrf_meta_tags %>

app/views/welcome/index.html.erb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<h1>Welcome Rails Demo</h1>
1+
<h1>Welcome Rails Capistrano</h1>

config/application.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# you've limited to :test, :development, or :production.
77
Bundler.require(*Rails.groups)
88

9-
module Demo
9+
module DemoRailsCapistrano
1010
class Application < Rails::Application
1111
# Settings in config/environments/* take precedence over those specified here.
1212
# Application configuration should go into files in config/initializers

config/deploy.rb

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
lock '3.4.0'
2+
3+
set :application, 'demo-rails-capistrano'
4+
set :deploy_user, 'deployer'
5+
6+
# Git configuration
7+
set :repo_url, '[email protected]:Dockbit/demo-rails-capistrano.git'
8+
set :scm, :git
9+
10+
# SSH settings
11+
set :ssh_options, {
12+
forward_agent: true,
13+
port: 22
14+
}
15+
16+
# Rbenv
17+
set :rbenv_type, :user
18+
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
19+
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
20+
set :rbenv_ruby, File.read('.ruby-version').strip
21+
22+
# Misc
23+
set :log_level, :info
24+
set :keep_releases, 5
25+
26+
# Linked application directories
27+
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
28+
29+
# Application config files
30+
set(:config_files, %w(
31+
nginx.conf
32+
unicorn.rb
33+
unicorn_init.sh
34+
log_rotation
35+
))
36+
37+
# Application executables
38+
set(:executable_config_files, %w(
39+
unicorn_init.sh
40+
))
41+
42+
# Linked system files
43+
set(:symlinks, [
44+
{
45+
source: 'nginx.conf',
46+
link: "/etc/nginx/sites-enabled/{{full_app_name}}"
47+
},
48+
{
49+
source: 'unicorn_init.sh',
50+
link: "/etc/init.d/unicorn_{{full_app_name}}"
51+
},
52+
{
53+
source: 'log_rotation',
54+
link: "/etc/logrotate.d/{{full_app_name}}"
55+
}
56+
])
57+
58+
namespace :deploy do
59+
before :deploy, 'deploy:setup_config'
60+
after :publishing, 'deploy:restart'
61+
after :finishing, 'deploy:cleanup'
62+
end

config/deploy/production.rb

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
set :stage, :production
2+
set :branch, 'master'
3+
set :full_app_name, "#{fetch(:application)}_#{fetch(:stage)}"
4+
set :host_name, 'demo-rails-capistrano.dockbit.com'
5+
6+
server fetch(:host_name), user: fetch(:deploy_user), roles: %w{ web app db }, primary: true
7+
8+
set :deploy_to, "/home/#{fetch(:deploy_user)}/apps/#{fetch(:full_app_name)}"
9+
set :rails_env, :production
10+
11+
set :unicorn_worker_count, 4
12+
set :enable_ssl, false

config/deploy/shared/log_rotation.erb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<%= fetch(:deploy_to) %>/shared/log/*.log {
2+
daily
3+
missingok
4+
rotate 52
5+
compress
6+
delaycompress
7+
notifempty
8+
sharedscripts
9+
endscript
10+
copytruncate
11+
}

config/deploy/shared/nginx.conf

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
user www-data;
2+
pid /run/nginx.pid;
3+
4+
### Performance optimizations
5+
# Based on: http://www.codestance.com/tutorials-archive/nginx-tuning-for-best-performance-255
6+
7+
worker_processes auto;
8+
worker_rlimit_nofile 100000;
9+
10+
events {
11+
worker_connections 4000;
12+
use epoll;
13+
multi_accept on;
14+
}
15+
16+
http {
17+
##
18+
# Basic Settings
19+
##
20+
21+
server_tokens off;
22+
sendfile on;
23+
tcp_nopush on;
24+
tcp_nodelay on;
25+
26+
keepalive_timeout 30;
27+
keepalive_requests 100000;
28+
client_max_body_size 4G;
29+
types_hash_max_size 2048;
30+
31+
reset_timedout_connection on;
32+
client_body_timeout 10;
33+
send_timeout 2;
34+
35+
##
36+
# Mime Types
37+
##
38+
39+
include /etc/nginx/mime.types;
40+
default_type application/octet-stream;
41+
42+
##
43+
# Logging Settings
44+
##
45+
46+
access_log /var/log/nginx/access.log;
47+
error_log /var/log/nginx/error.log;
48+
49+
##
50+
# Gzip Settings
51+
##
52+
53+
gzip on;
54+
gzip_min_length 10240;
55+
gzip_proxied expired no-cache no-store private auth;
56+
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
57+
gzip_disable "MSIE [1-6]\.";
58+
59+
##
60+
# Virtual Host Configs
61+
##
62+
63+
include /etc/nginx/conf.d/*.conf;
64+
include /etc/nginx/sites-enabled/*;
65+
}

0 commit comments

Comments
 (0)