capistrano-vps 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +105 -0
  6. data/Rakefile +2 -0
  7. data/bootstrap.sh +64 -0
  8. data/capistrano-vps.gemspec +19 -0
  9. data/lib/capistrano-vps.rb +1 -0
  10. data/lib/capistrano-vps/recipes/base.rb +32 -0
  11. data/lib/capistrano-vps/recipes/check.rb +15 -0
  12. data/lib/capistrano-vps/recipes/elasticsearch.rb +29 -0
  13. data/lib/capistrano-vps/recipes/haproxy.rb +30 -0
  14. data/lib/capistrano-vps/recipes/imagemagick.rb +10 -0
  15. data/lib/capistrano-vps/recipes/libcurl.rb +11 -0
  16. data/lib/capistrano-vps/recipes/libxml.rb +11 -0
  17. data/lib/capistrano-vps/recipes/mongodb.rb +21 -0
  18. data/lib/capistrano-vps/recipes/nginx.rb +29 -0
  19. data/lib/capistrano-vps/recipes/nodejs.rb +11 -0
  20. data/lib/capistrano-vps/recipes/postgresql_client.rb +114 -0
  21. data/lib/capistrano-vps/recipes/postgresql_server.rb +41 -0
  22. data/lib/capistrano-vps/recipes/rabbitmq.rb +23 -0
  23. data/lib/capistrano-vps/recipes/rbenv.rb +50 -0
  24. data/lib/capistrano-vps/recipes/redis.rb +28 -0
  25. data/lib/capistrano-vps/recipes/resque.rb +27 -0
  26. data/lib/capistrano-vps/recipes/ssh_agent.rb +17 -0
  27. data/lib/capistrano-vps/recipes/templates/haproxy.erb +1 -0
  28. data/lib/capistrano-vps/recipes/templates/haproxy_conf.erb +58 -0
  29. data/lib/capistrano-vps/recipes/templates/nginx_haproxy.erb +44 -0
  30. data/lib/capistrano-vps/recipes/templates/nginx_unicorn.erb +37 -0
  31. data/lib/capistrano-vps/recipes/templates/postgresql.yml.erb +8 -0
  32. data/lib/capistrano-vps/recipes/templates/redis.conf.erb +1 -0
  33. data/lib/capistrano-vps/recipes/templates/resque.rake.erb +97 -0
  34. data/lib/capistrano-vps/recipes/templates/unicorn.rb.erb +32 -0
  35. data/lib/capistrano-vps/recipes/templates/unicorn_init.erb +84 -0
  36. data/lib/capistrano-vps/recipes/thin.rb +35 -0
  37. data/lib/capistrano-vps/recipes/unicorn.rb +30 -0
  38. data/lib/capistrano-vps/recipes/web.rb +15 -0
  39. data/lib/capistrano-vps/recipes/wkhtmltoimage.rb +16 -0
  40. data/lib/capistrano-vps/version.rb +3 -0
  41. data/lib/rails/generators/vps/recipes/install/install_generator.rb +25 -0
  42. data/lib/rails/generators/vps/recipes/install/templates/deploy.rb +46 -0
  43. data/lib/rails/generators/vps/recipes/install/templates/production.rb +1 -0
  44. data/lib/rails/generators/vps/recipes/install/templates/staging.rb +1 -0
  45. metadata +99 -0
@@ -0,0 +1,11 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ namespace :nodejs do
3
+ desc "Install the latest relase of Node.js"
4
+ task :install, roles: :app do
5
+ run "#{sudo} add-apt-repository -y ppa:chris-lea/node.js"
6
+ run "#{sudo} apt-get -y update"
7
+ run "#{sudo} apt-get -y install nodejs"
8
+ end
9
+ after "cap_vps:prepare", "nodejs:install"
10
+ end
11
+ end
@@ -0,0 +1,114 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ db_server = find_servers(:roles => :db).first
3
+ db_ip = (db_server ? db_server.options[:internal] || 'localhost' : 'localhost')
4
+ set_default(:postgresql_host, db_ip)
5
+ set_default(:postgresql_user) { application }
6
+ set_default(:postgresql_password) { (0...10).map{(65+rand(60)).chr}.join.gsub('`', ':') } #random password instead, Capistrano::CLI.password_prompt "Choose PostgreSQL Password: " }
7
+ set_default(:postgresql_database) { "#{application}_production" }
8
+ set_default(:postgresql_host) { db_ip }
9
+
10
+ namespace :postgresql_client do
11
+ desc "Install dev libraries PostgreSQL."
12
+ task :install, roles: :db, only: {primary: true} do
13
+ run "#{sudo} add-apt-repository -y ppa:pitti/postgresql"
14
+ run "#{sudo} apt-get -y update"
15
+ run "#{sudo} apt-get -y install libpq-dev"
16
+ end
17
+ after "cap_vps:prepare", "postgresql_client:install"
18
+
19
+ desc "Create a database for this application."
20
+ task :create_database, roles: :db_server do
21
+ run %Q{#{sudo} -u postgres psql -c "create user #{postgresql_user} with password '#{postgresql_password}';"}
22
+ run %Q{#{sudo} -u postgres psql -c "create database #{postgresql_database} owner #{postgresql_user};"}
23
+ end
24
+ after "deploy:setup", "postgresql_client:create_database"
25
+
26
+ desc "Generate the database.yml configuration file."
27
+ task :setup, roles: :app do
28
+ run "mkdir -p #{shared_path}/config"
29
+ template "postgresql.yml.erb", "#{shared_path}/config/database.yml"
30
+ end
31
+ after "deploy:setup", "postgresql_client:setup"
32
+
33
+ desc "Symlink the database.yml file into latest release"
34
+ task :symlink, roles: :app do
35
+ run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
36
+ end
37
+ after "deploy:finalize_update", "postgresql_client:symlink"
38
+ end
39
+ namespace :db do
40
+ require 'yaml'
41
+
42
+ def sql_filename
43
+ @sql_filename ||= "#{application}_#{env}_#{Time.now.strftime '%Y-%m-%d'}.sql"
44
+ end
45
+
46
+ def filename
47
+ @filename ||= "#{sql_filename}.bz2"
48
+ end
49
+
50
+ def env
51
+ @env ||= ENV['RAILS_ENV'] || ENV['DB'] || 'production'
52
+ end
53
+
54
+
55
+
56
+ desc "Dump database"
57
+ task :dump, :role => :db_server do
58
+ download("#{shared_path}/config/database.yml", "tmp/database.yml", roles: :app)
59
+ remote_database = YAML::load_file('tmp/database.yml')
60
+ on_rollback { delete "/tmp/#{@filename}" }
61
+ run %Q{#{sudo} -u postgres pg_dump --clean --no-owner --no-privileges #{remote_database['production']['database']} | bzip2 > /tmp/#{filename}}, roles: :db_server
62
+ end
63
+
64
+ desc "Get database"
65
+ task :get, :role => :db_server do
66
+ download("/tmp/#{filename}", "tmp/#{filename}", roles: :db_server)
67
+ #run_locally("bzip2 -df tmp/#{@filename}")
68
+ end
69
+
70
+ desc "Import database"
71
+ task :import, :role => :db_server do
72
+ download("#{shared_path}/config/database.yml", "tmp/database.yml", roles: :app)
73
+ database = YAML::load_file('tmp/database.yml')
74
+ upload( "tmp/#{filename}", "/tmp/#{filename}", roles: :db_server)
75
+ run "bzip2 -df /tmp/#{filename}", roles: :db_server
76
+ run "PGPASSWORD=#{database['production']['password']} psql -U #{database['production']['username']} -h #{database['production']['host']} #{database['production']['database']} < /tmp/#{sql_filename}", roles: :db_server
77
+ end
78
+
79
+ desc "Get database file"
80
+ task :pull do
81
+ dump
82
+ get
83
+ end
84
+
85
+ desc "Push database file and import"
86
+ task :push, :role => :db_server do
87
+ import
88
+ end
89
+
90
+
91
+ desc "Duplicate database"
92
+ task :duplicate, :role => :db_server do
93
+ dump
94
+ get
95
+ # import
96
+ end
97
+
98
+ desc "Restore from ftp"
99
+ task :restore, :role => :db_server do
100
+
101
+ end
102
+
103
+ # TODO add a command to alter user password:
104
+ # * sudo -u postgres psql -c "ALTER USER appuser WITH PASSWORD 'password';"
105
+ # * update databse.yml
106
+ # * manage putistage environment (staging)
107
+
108
+
109
+ end
110
+
111
+
112
+
113
+
114
+ end
@@ -0,0 +1,41 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ set_default(:postgresql_host, "localhost")
3
+ set_default(:postgresql_user) { application }
4
+ # set_default(:postgresql_password) { Capistrano::CLI.password_prompt "Choose PostgreSQL Password: " }
5
+ set_default(:postgresql_database) { "#{application}_production" }
6
+ namespace :postgresql_server do
7
+ desc "Install the latest stable release of PostgreSQL."
8
+ task :install, roles: :db_server do
9
+ run "#{sudo} add-apt-repository -y ppa:pitti/postgresql"
10
+ run "#{sudo} apt-get -y update"
11
+ run "#{sudo} apt-get -y install postgresql"
12
+ end
13
+ after "cap_vps:prepare", "postgresql_server:install"
14
+
15
+ # task :install_dev, roles: :db, only: {primary: true} do
16
+ # run "#{sudo} apt-get -y install libpq-dev"
17
+ # end
18
+ # after "server:prepare", "postgresql:install_dev"
19
+
20
+
21
+ # desc "Create a database for this application."
22
+ # task :create_database, roles: :db_server do
23
+ # run %Q{#{sudo} -u postgres psql -c "create user #{postgresql_user} with password '#{postgresql_password}';"}
24
+ # run %Q{#{sudo} -u postgres psql -c "create database #{postgresql_database} owner #{postgresql_user};"}
25
+ # end
26
+ # after "deploy:setup", "postgresql:create_database"
27
+
28
+ # desc "Generate the database.yml configuration file."
29
+ # task :setup, roles: :app do
30
+ # run "mkdir -p #{shared_path}/config"
31
+ # template "postgresql.yml.erb", "#{shared_path}/config/database.yml"
32
+ # end
33
+ # after "deploy:setup", "postgresql:setup"
34
+
35
+ # desc "Symlink the database.yml file into latest release"
36
+ # task :symlink, roles: :app do
37
+ # run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
38
+ # end
39
+ # after "deploy:finalize_update", "postgresql:symlink"
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ namespace :rabbitmq do
3
+ desc "Install the latest relase of Node.js"
4
+ task :install, roles: :app do
5
+ run "#{sudo} wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc"
6
+ run "#{sudo} apt-key add rabbitmq-signing-key-public.asc"
7
+ run %q{#{sudo} echo "deb http://www.rabbitmq.com/debian/ testing main" >> /etc/apt/sources.list}
8
+ run "#{sudo} apt-get -y update"
9
+ run "#{sudo} apt-get -y install rabbitmq"
10
+ end
11
+ after "cap_vps:prepare", "rabbitmq:install"
12
+
13
+ desc "Start RabbitMQ"
14
+ task :start do
15
+ run "#{sudo} invoke-rc.d rabbitmq-server stop/start"
16
+ end
17
+
18
+ desc "Stop RabbitMQ"
19
+ task :stop do
20
+ run "#{sudo} rabbitmqctl stop"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,50 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ set_default :ruby_version, "2.0.0p195"
3
+ # set_default :rbenv_bootstrap, "bootstrap-ubuntu-11-10"
4
+
5
+ namespace :rbenv do
6
+ desc "Install rbenv, Ruby, and the Bundler gem"
7
+ task :install, roles: :app do
8
+ run "#{sudo} apt-get -y install curl git-core"
9
+ run "curl -L https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash"
10
+ bashrc = <<-BASHRC
11
+ if [ -d $HOME/.rbenv ]; then
12
+ export PATH="$HOME/.rbenv/bin:$PATH"
13
+ eval "$(rbenv init -)"
14
+ fi
15
+ BASHRC
16
+ put bashrc, "/tmp/rbenvrc"
17
+ run "cat /tmp/rbenvrc ~/.bashrc > ~/.bashrc.tmp"
18
+ run "mv ~/.bashrc.tmp ~/.bashrc"
19
+ run %q{export PATH="$HOME/.rbenv/bin:$PATH"}
20
+ run %q{eval "$(rbenv init -)"}
21
+ run "#{sudo} apt-get -y install build-essential"
22
+ run "#{sudo} apt-get -y install zlib1g-dev libssl-dev"
23
+ run "#{sudo} apt-get -y install libreadline-gplv2-dev"
24
+ rbenv.install_ruby
25
+ run "gem install bundler --no-ri --no-rdoc"
26
+ run "rbenv rehash"
27
+ end
28
+
29
+ desc "Upgrade rbenv"
30
+ task :upgrade, roles: :app do
31
+ run "cd ~/.rbenv; git pull"
32
+ run "cd ~/.rbenv/plugins/ruby-build; git pull"
33
+ end
34
+
35
+ desc "Install ruby"
36
+ task :install_ruby, roles: :app do
37
+ run "export RUBY_GC_MALLOC_LIMIT=60000000; export RUBY_FREE_MIN=200000" #"; curl https://raw.github.com/gist/4637375/rbenv.sh | sh "
38
+
39
+ # run "curl https://raw.github.com/gist/1688857/2-#{ruby_version}-patched.sh > /tmp/#{ruby_version}-perf"
40
+ # run "rbenv install /tmp/#{ruby_version}-perf"
41
+ run "rbenv install #{ruby_version}"
42
+ run "rbenv global #{ruby_version}"
43
+ run "gem install bundler --no-ri --no-rdoc"
44
+ run "rbenv rehash"
45
+ end
46
+
47
+ after "cap_vps:prepare", "rbenv:install"
48
+ before "rbenv:install_ruby", "rbenv:upgrade"
49
+ end
50
+ end
@@ -0,0 +1,28 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ namespace :redis do
3
+
4
+ desc "Install the latest release of Redis"
5
+ task :install, roles: :app do
6
+ run "#{sudo} add-apt-repository -y ppa:chris-lea/redis-server"
7
+ run "#{sudo} apt-get -y update"
8
+ run "#{sudo} apt-get -y install redis-server"
9
+ end
10
+ after "cap_vps:prepare", "redis:install"
11
+
12
+ # desc "Setup redis configuration for this application"
13
+ # task :setup, roles: :web do
14
+ # template "redis.conf.erb", "/tmp/redis.conf"
15
+ # run "#{sudo} mv /tmp/redis.conf /etc/redis/redis.conf"
16
+ # restart
17
+ # end
18
+ # after "deploy:setup", "redis:setup"
19
+
20
+ %w[start stop restart].each do |command|
21
+ desc "#{command} redis"
22
+ task command, roles: :web do
23
+ run "#{sudo} service redis-server #{command}"
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+
3
+ def run_remote_rake(rake_cmd)
4
+ rake_args = ENV['RAKE_ARGS'].to_s.split(',')
5
+ cmd = "cd #{fetch(:latest_release)} && #{fetch(:rake, "rake")} RAILS_ENV=#{fetch(:rails_env, "production")} #{rake_cmd}"
6
+ cmd += "['#{rake_args.join("','")}']" unless rake_args.empty?
7
+ run cmd
8
+ set :rakefile, nil if exists?(:rakefile)
9
+ end
10
+
11
+ namespace :resque do
12
+ namespace :worker do
13
+ after "deploy:symlink", "deploy:restart_workers"
14
+ after "deploy:restart_workers", "deploy:restart_scheduler"
15
+
16
+ desc "Restart Resque Workers"
17
+ task :restart, :roles => :db do
18
+ run_remote_rake "resque:restart_workers"
19
+ end
20
+
21
+ desc "Restart Resque scheduler"
22
+ task :scheduler, :roles => :db do
23
+ run_remote_rake "resque:restart_scheduler"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ Capistrano::Configuration.instance(true).load do
2
+ task :check_for_ssh_agent do
3
+ pid = ENV["SSH_AGENT_PID"]
4
+ raise %|No ssh-agent active (cannot authenticate to bitbucket/github without it.) Try running "eval `ssh-agent`; ssh-add".| if pid.nil? or pid == "" or pid.to_i == 0
5
+
6
+ begin
7
+ Process.getpgid(pid.to_i)
8
+ rescue Errno::ESRCH
9
+ raise %|The ssh-agent at pid #{pid} has died (cannot authenticate to bitbucket/github without it.) Try running "eval `ssh-agent`; ssh-add".|
10
+ end
11
+
12
+ if `ssh-add -L` =~ /no identities/
13
+ raise %|The ssh-agent at pid #{pid} has no keys. Have you run "ssh-add"?|
14
+ end
15
+ end
16
+ before "deploy:update", "check_for_ssh_agent"
17
+ end
@@ -0,0 +1 @@
1
+ ENABLE=1
@@ -0,0 +1,58 @@
1
+ # this config needs haproxy-1.1.28 or haproxy-1.2.1
2
+ # Config PROXY
3
+
4
+ global
5
+ daemon
6
+ pidfile /var/run/haproxy.pid
7
+
8
+ defaults
9
+ mode http
10
+ retries 5
11
+ option abortonclose
12
+ option redispatch
13
+ option abortonclose # enable early dropping of aborted requests from pending queue
14
+ option httpchk # enable HTTP protocol to check on servers health
15
+ option httpclose
16
+ option forwardfor header X-Real-IP except 127.0.0.1 # enable insert of X-Forwarded-For headers
17
+ option http-no-delay
18
+ balance roundrobin
19
+ option httplog
20
+ option dontlognull
21
+
22
+ maxconn 4096
23
+
24
+ timeout connect 5000
25
+ timeout client 50000
26
+ timeout server 50000
27
+ clitimeout 60000 # maximum inactivity time on the client side
28
+ srvtimeout 30000 # maximum inactivity time on the server side
29
+ timeout connect 4000 # maximum time to wait for a connection attempt to a server to succeed
30
+
31
+ stats enable # enable web-stats at /haproxy?stats
32
+ stats auth admin:pass # force HTTP Auth to view stats
33
+ stats refresh 5s # refresh rate of stats page
34
+ monitor-uri /haproxy-pf?monitor
35
+
36
+ frontend <%= application %> *:8000
37
+ default_backend <%= application %>-thins
38
+
39
+ backend <%= application %>-thins
40
+ server server-1 127.0.0.1:9001 weight 1
41
+ #check inter 20000 fastinter 1000 fall 1 maxqueue 2
42
+ server server-2 127.0.0.1:9002 weight 1
43
+ #check inter 20000 fastinter 1000 fall 1 maxqueue 2
44
+
45
+
46
+ # server app1_1 192.168.34.23:8080 cookie app1inst1 check inter 2000 rise 2 fall 5
47
+ # option httpclose # disable keep-alive
48
+ # rspidel ^Set-cookie:\ IP= # do not let this cookie tell our internal IP address
49
+
50
+ #errorloc 502 http://192.168.114.58/error502.html
51
+ #errorfile 503 /etc/haproxy/errors/503.http
52
+ errorfile 400 /etc/haproxy/errors/400.http
53
+ errorfile 403 /etc/haproxy/errors/403.http
54
+ errorfile 408 /etc/haproxy/errors/408.http
55
+ errorfile 500 /etc/haproxy/errors/500.http
56
+ errorfile 502 /etc/haproxy/errors/502.http
57
+ errorfile 503 /etc/haproxy/errors/503.http
58
+ errorfile 504 /etc/haproxy/errors/504.http
@@ -0,0 +1,44 @@
1
+ server {
2
+ listen 80;
3
+ server_name <%= application %>.com;
4
+ root <%= current_path %>/public;
5
+ access_log /var/log/nginx/<%= application %>.access.log combined buffer=32k;
6
+ keepalive_requests 20;
7
+ gzip on;
8
+ gzip_vary on;
9
+ large_client_header_buffers 4 16k;
10
+ client_max_body_size 8M;
11
+ keepalive_timeout 10;
12
+
13
+ location ^~ /assets/ {
14
+ gzip_static on;
15
+ expires max;
16
+ add_header Cache-Control public;
17
+ }
18
+
19
+ if (-f $document_root/maintenance.html){
20
+ rewrite ^(.*)$ /maintenance.html last;
21
+ break;
22
+ }
23
+
24
+ location / {
25
+ # needed for HTTPS
26
+ proxy_set_header Host $http_host;
27
+ proxy_max_temp_file_size 0;
28
+ proxy_headers_hash_max_size 1024;
29
+ proxy_headers_hash_bucket_size 128;
30
+ proxy_buffer_size 2m;
31
+ proxy_busy_buffers_size 2m;
32
+ proxy_buffers 4 1m;
33
+
34
+ proxy_pass http://localhost:8000;
35
+ proxy_redirect off;
36
+ proxy_set_header Host $host;
37
+ # needed to forward user's IP address to rails
38
+ proxy_set_header X-Real-IP $remote_addr;
39
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
40
+ }
41
+
42
+ error_page 500 502 503 504 /500.html;
43
+
44
+ }
@@ -0,0 +1,37 @@
1
+ upstream unicorn-<%= application %> {
2
+ server unix:/tmp/unicorn.<%= application %>.sock fail_timeout=0;
3
+ }
4
+
5
+ server {
6
+ listen 80;
7
+ server_name <%= application %>.com;
8
+ root <%= current_path %>/public;
9
+ access_log /var/log/nginx/<%= application %>.access.log combined buffer=32k;
10
+ keepalive_requests 20;
11
+ gzip on;
12
+ gzip_vary on;
13
+ large_client_header_buffers 4 16k;
14
+ client_max_body_size 8M;
15
+ keepalive_timeout 10;
16
+
17
+ location ^~ /assets/ {
18
+ gzip_static on;
19
+ expires max;
20
+ add_header Cache-Control public;
21
+ }
22
+
23
+ if (-f $document_root/maintenance.html){
24
+ rewrite ^(.*)$ /maintenance.html last;
25
+ break;
26
+ }
27
+
28
+ try_files $uri/index.html $uri @unicorn;
29
+ location @unicorn {
30
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
31
+ proxy_set_header Host $http_host;
32
+ proxy_redirect off;
33
+ proxy_pass http://unicorn-<%= application %>;
34
+ }
35
+
36
+ error_page 500 502 503 504 /500.html;
37
+ }