ratchetify 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ec4df90fc1d35e8dbc3e926941de1b4ddf40131
4
+ data.tar.gz: f83dc562279ef6e25fd6096d3b64f6bf24d8b988
5
+ SHA512:
6
+ metadata.gz: fa70a0efa1a00b16758a182ba0453fc864ae859124f0ce3b41412cb14f3fb2db1e1b7404b74a7277f62eb5e157fad72fca14db48ac2770c00471b514bcd39c5d
7
+ data.tar.gz: 1c924f17be19a6de26379b7b2014ab8ae890cd78afdd0a9bead9abce262015548fde636dd3c13fe29445cdb82aa25d74ce595be6792ce85205164f5da8d3befa
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .project
19
+ .settings
20
+ .DS_Store
data/Capfile.example ADDED
@@ -0,0 +1,22 @@
1
+ # ratchetify recipes
2
+ require 'ratchetify'
3
+
4
+ # the application's name
5
+ set :application, 'yourapp'
6
+ set :host, 'www'
7
+ set :domain, 'yourapp.com'
8
+
9
+ # SSH user/password
10
+ set :user, 'uberspace_user'
11
+ set :password, 'uberspace_user_password'
12
+
13
+ role :web, "some_server.uberspace.de" # Your HTTP server, Apache/etc
14
+ role :db, "some_server.uberspace.de"
15
+
16
+ set :repo, "https://github.com/you/yourapp.git"
17
+ set :repo_password, 'your_github_password'
18
+ set :branch, 'master'
19
+
20
+ set :daemon_port, 76543 # a random port. Make sure no one else uses it
21
+
22
+ # there are a couple more attributes, but normally you don't need to change them. See lib/ratchetify.rb and lib/ratchetify/base.rb for details.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in uberspacify.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Michael Kuehl, michael@ratchet.cc
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Ratchetify
2
+
3
+ Ratchetify helps you deploy a Ruby on Rails app on Uberspace (uberspace.de), a really cool shared hosting provider.
4
+
5
+ All the magic is built into a couple nice Capistrano scripts. Ratchetify will create an environment for your app, run it in standalone mode, monitor it using Daemontools, and configure Apache to reverse-proxy to it. Ratchetify will also retrieve your MySQL password, create a dedicated database for your app and create a `database.yml`.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's `Gemfile`:
10
+
11
+ ```ruby
12
+ gem 'ratchetify', :git => 'https://github.com/ratchetcc/ratchetify.git'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ This will install ratchetify, Capistrano 2.x and all dependent gems for you.
20
+
21
+ ## How to use ratchetify
22
+
23
+ There is a sample [capfile](https://github.com/ratchetcc/ratchetify/blob/master/Capfile.example) that shows the most important settings you need to get started. In addition to the
24
+ attributes used in the Capfile, there are more attributes pre-set in lib/ratchetify.rb and lib/ratchetify/base.rb but usually there is no need to change any of these.
25
+
26
+ This tools is highly opinionated i.e. all the settings, the way how I run the app etc. are THE WAY I LIKE IT. This does not mean it can not be done differently or that it is the best way to do it ...
27
+
28
+ ## Credits
29
+
30
+ The original gem was created by [Jan Schulz-Hofen](https://github.com/yeah/uberspacify).
31
+
32
+ ## License
33
+
34
+ MIT; Copyright (c) 2014 ratchet.cc
35
+
36
+ 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:
37
+
38
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
39
+
40
+ 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.
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/rat ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'capistrano/cli'
3
+ Capistrano::CLI.execute
@@ -0,0 +1,23 @@
1
+
2
+ require 'bundler/capistrano'
3
+
4
+ def abort_red(msg)
5
+ abort " * \e[#{1};31mERROR: #{msg}\e[0m"
6
+ end
7
+
8
+ Capistrano::Configuration.instance.load do
9
+
10
+ # required variables
11
+ _cset(:user) { abort_red "Please configure your Uberspace user using 'set :user, <username>'" }
12
+ _cset(:repository) { abort_red "Please configure your code repository using 'set :repository, <repo uri>'" }
13
+
14
+ # other variables
15
+ _cset(:deploy_via) { :remote_cache }
16
+ _cset(:branch) { 'master' }
17
+
18
+ # internal variables, don't mess with them unsless you know what you do !
19
+ set(:use_sudo) { false }
20
+ ssh_options[:forward_agent] = true # use the keys for the person running the cap command to check out the app
21
+ default_run_options[:pty] = true # needed for git password prompts
22
+
23
+ end
@@ -0,0 +1,23 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+
7
+ desc "Tasks to add/remove domains (web only)"
8
+ namespace :domain do
9
+
10
+ desc "Add a fully qualified domain and wildcard domain if specified"
11
+ task :add do
12
+ run "uberspace-add-domain -d #{fetch :host}.#{fetch :domain} -w"
13
+ run "uberspace-add-domain -d #{fetch :domain} -w" unless (wildcard_domain == false)
14
+ end
15
+
16
+ desc "Removes a fully qualified domain and wildcard domain if specified"
17
+ task :remove do
18
+ run "uberspace-del-domain -d #{fetch :host}.#{fetch :domain} -w"
19
+ run "uberspace-del-domain -d #{fetch :domain} -w" unless (wildcard_domain == false)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,74 @@
1
+ module Capistrano
2
+ class CLI
3
+ module Help
4
+
5
+ def task_list(config, pattern = true) #:nodoc:
6
+ tool_output = options[:tool]
7
+
8
+ if pattern.is_a?(String)
9
+ tasks = config.task_list(:all).select {|t| t.fully_qualified_name =~ /#{pattern}/}
10
+ end
11
+ if tasks.nil? || tasks.length == 0
12
+ warn "Pattern '#{pattern}' not found. Listing all tasks.\n\n" if !tool_output && !pattern.is_a?(TrueClass)
13
+ tasks = config.task_list(:all)
14
+ end
15
+
16
+ if tasks.empty?
17
+ warn "There are no tasks available. Please specify a recipe file to load." unless tool_output
18
+ else
19
+ all_tasks_length = tasks.length
20
+ if options[:verbose].to_i < 1
21
+ tasks = tasks.reject { |t| t.description.empty? || t.description =~ /^\[internal\]/ }
22
+ end
23
+
24
+ tasks = tasks.sort_by { |task| task.fully_qualified_name }
25
+
26
+ longest = tasks.map { |task| task.fully_qualified_name.length }.max
27
+ max_length = output_columns - longest - LINE_PADDING
28
+ max_length = MIN_MAX_LEN if max_length < MIN_MAX_LEN
29
+
30
+ tasks.each do |task|
31
+ if tool_output
32
+ puts "rat #{task.fully_qualified_name}" # monkey patched
33
+ else
34
+ puts "rat %-#{longest}s # %s" % [task.fully_qualified_name, task.brief_description(max_length)] # monkey patched
35
+ end
36
+ end
37
+
38
+ unless tool_output
39
+ if all_tasks_length > tasks.length
40
+ puts
41
+ puts "Some tasks were not listed, either because they have no description,"
42
+ puts "or because they are only used internally by other tasks. To see all"
43
+ puts "tasks, type `#{File.basename($0)} -vT'."
44
+ end
45
+
46
+ puts
47
+ puts "Extended help may be available for these tasks."
48
+ puts "Type `#{File.basename($0)} -e taskname' to view it."
49
+ end
50
+ end
51
+ end
52
+
53
+ def explain_task(config, name) #:nodoc:
54
+ task = config.find_task(name)
55
+ if task.nil?
56
+ warn "The task `#{name}' does not exist."
57
+ else
58
+ puts "-" * HEADER_LEN
59
+ puts "rat #{name}" # monkey patched
60
+ puts "-" * HEADER_LEN
61
+
62
+ if task.description.empty?
63
+ puts "There is no description for this task."
64
+ else
65
+ puts format_text(task.description)
66
+ end
67
+
68
+ puts
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,69 @@
1
+ #
2
+ # usefull methods that make life easier
3
+ #
4
+
5
+ #
6
+ # dirs and other constants
7
+ #
8
+
9
+ def webroot_dir
10
+ "/var/www/virtual/#{user}"
11
+ end
12
+
13
+ def deploy_root
14
+ "#{webroot_dir}/apps"
15
+ end
16
+
17
+ def deploy_dir
18
+ "#{deploy_root}/#{application}"
19
+ end
20
+
21
+ def conf_dir
22
+ "/home/#{user}/aconf"
23
+ end
24
+
25
+ def daemon_service
26
+ "run-#{application}"
27
+ end
28
+
29
+ #
30
+ # file and dir handling
31
+ #
32
+
33
+ def file_exists?(full_path)
34
+ 'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
35
+ end
36
+
37
+ def dir_exists?(full_path)
38
+ 'true' == capture("if [ -d #{full_path} ]; then echo 'true'; fi").strip
39
+ end
40
+
41
+ def create_dir(full_path, owner=nil)
42
+ run "mkdir #{full_path} -p"
43
+ if owner
44
+ run "chown #{owner} #{full_path}"
45
+ end
46
+ end
47
+
48
+ def delete_dir(full_path)
49
+ if dir_exists? full_path
50
+ run "rm -Rf #{full_path}"
51
+ end
52
+ end
53
+
54
+ def delete_file(full_path)
55
+ if file_exists? full_path
56
+ run "rm #{full_path}"
57
+ end
58
+ end
59
+
60
+ #
61
+ # working with git
62
+ #
63
+ def branch?(full_path)
64
+ capture("cd #{full_path} && git branch | grep '*'")
65
+ end
66
+
67
+ def on_branch?(full_path, branch)
68
+ branch?(full_path).include? branch
69
+ end
@@ -0,0 +1,127 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+ require 'ratchetify/setup'
7
+ require 'ratchetify/domain'
8
+ require 'ratchetify/service'
9
+
10
+ before "create:rails", "setup:environment"
11
+ after "create:rails", "service:create"
12
+ after "create:rails", "domain:add"
13
+
14
+ desc "Deploy an app for the first time"
15
+ namespace :create do
16
+
17
+ desc "Deploy an RAILS app to uberspace"
18
+ task :rails do
19
+ create_repo
20
+ create_and_configure_database
21
+ create_reverse_proxy
22
+ config_rails_app
23
+ finalize
24
+ end
25
+
26
+ task :create_repo do
27
+ # clone the repo first
28
+ git_cmd = "cd #{deploy_root} && git clone #{fetch :repo} #{fetch :application}"
29
+
30
+ run git_cmd do |channel, stream, out|
31
+ if out =~ /Password:/
32
+ channel.send_data("#{fetch :repo_password}\n")
33
+ else
34
+ puts out
35
+ end
36
+ end
37
+
38
+ # switch to the specified branch
39
+ run "cd #{deploy_dir} && git checkout -b #{fetch :branch}" unless on_branch? deploy_dir, "#{fetch :branch}"
40
+
41
+ end # task :create_repo
42
+
43
+ task :create_and_configure_database do
44
+
45
+ # extract user & password
46
+ my_cnf = capture('cat ~/.my.cnf')
47
+
48
+ my_cnf.match(/^user=(\w+)/)
49
+ mysql_user = $1
50
+ my_cnf.match(/^password=(\w+)/)
51
+ mysql_pwd = $1
52
+
53
+ # create the database
54
+ mysql_database = "#{user}_#{application}" # 'application' MUST NOT contain any '-' !!!
55
+ run "mysql -e 'CREATE DATABASE IF NOT EXISTS #{mysql_database} CHARACTER SET utf8 COLLATE utf8_general_ci;'"
56
+
57
+ # create the database.yml file
58
+ database_yml = <<-EOF
59
+ production:
60
+ adapter: mysql2
61
+ encoding: utf8
62
+ database: #{mysql_database}
63
+ pool: 15
64
+ username: #{mysql_user}
65
+ password: #{mysql_pwd}
66
+ host: localhost
67
+ socket: /var/lib/mysql/mysql.sock
68
+ timeout: 10000
69
+
70
+ EOF
71
+ # upload the database.yml file
72
+ put database_yml, "#{deploy_dir}/config/database.yml"
73
+
74
+ end # task :create_and_configure_database
75
+
76
+ task :create_reverse_proxy do
77
+
78
+ # .htaccess
79
+ htaccess = <<-EOF
80
+ RewriteEngine On
81
+ RewriteBase /
82
+ RewriteCond %{REQUEST_FILENAME} !-f
83
+ RewriteRule ^(.*)$ http://localhost:#{daemon_port}/$1 [P]
84
+ EOF
85
+
86
+ # place the .htaccess file
87
+ put htaccess, "#{deploy_dir}/.htaccess"
88
+ run "chmod +r #{deploy_dir}/.htaccess"
89
+
90
+ end # task :create_reverse_proxy
91
+
92
+ task :config_rails_app do
93
+ # run bundle install first
94
+ run "cd #{deploy_dir} && bundle install --path ~/.gem"
95
+
96
+ # application.yml should normally be on the .gitignore list, however you application might need
97
+ # a basic configuration file to e.g. load seed data. Provide such a basic file as 'application.example.yml'
98
+ # and it will be used to configure the app initially.
99
+
100
+ # create a default application.yml file if non was provided
101
+ if not file_exists? "#{deploy_dir}/config/application.yml"
102
+ if file_exists? "#{deploy_dir}/config/application.example.yml"
103
+ run "cd #{deploy_dir}/config && cp application.example.yml application.yml"
104
+ end
105
+ end
106
+
107
+ # run rake db:migrate to create all tables etc
108
+ run "cd #{deploy_dir} && bundle exec rake db:migrate RAILS_ENV=#{fetch :environment}"
109
+
110
+ # run rake db:seed to load seed data
111
+ run "cd #{deploy_dir} && bundle exec rake db:seed RAILS_ENV=#{fetch :environment}"
112
+
113
+ # compile assets from the asset pipeline
114
+ run "cd #{deploy_dir} && bundle exec rake assets:precompile RAILS_ENV=#{fetch :environment}"
115
+
116
+ # create symbolic links so that apache will find the assets
117
+ run "cd #{deploy_dir} && ln -s public/assets assets"
118
+ end
119
+
120
+ task :finalize do
121
+ # create symbolic links..
122
+ run "cd #{webroot_dir} && ln -s #{deploy_dir} #{fetch :host}.#{fetch :domain}"
123
+ run "cd #{webroot_dir} && ln -s #{deploy_dir} #{fetch :domain}" unless (wildcard_domain == false)
124
+ end
125
+
126
+ end # namespace
127
+ end
@@ -0,0 +1,30 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ desc "Setup ruby interpreter and tools"
5
+ namespace :setup do
6
+ desc "Setup ruby interpreter and tools"
7
+ task :ruby do
8
+
9
+ # script to setup ruby
10
+ ruby_script = <<-EOF
11
+
12
+ # ruby #{ruby_version} environment
13
+ export PATH=/package/host/localhost/ruby-#{ruby_version}/bin:$PATH
14
+ export PATH=$HOME/.gem/ruby/#{ruby_version}/bin:$PATH
15
+ EOF
16
+
17
+ # setup the ruby environment
18
+ put ruby_script, "/home/#{user}/ruby_scrip"
19
+ run "cat /home/#{user}/ruby_scrip >> /home/#{user}/.bashrc"
20
+
21
+ # configure ruby
22
+ run "echo 'gem: --user-install --no-rdoc --no-ri' > ~/.gemrc"
23
+ run "gem install bundler"
24
+
25
+ # cleanup
26
+ run "rm /home/#{user}/ruby_scrip"
27
+
28
+ end # task :ruby
29
+ end
30
+ end
@@ -0,0 +1,118 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+
7
+ desc "Tasks to start/stop/restart the app server"
8
+ namespace :service do
9
+ desc "Start the app server"
10
+ task :start do
11
+ run "svc -u ~/service/#{daemon_service}"
12
+ end
13
+
14
+ desc "Stop the app server"
15
+ task :stop do
16
+ run "svc -d ~/service/#{daemon_service}"
17
+ end
18
+
19
+ desc "Restart the app server"
20
+ task :restart do
21
+ run "svc -du ~/service/#{daemon_service}"
22
+ end
23
+
24
+ task :create do
25
+ create_service_thin # the only option for now
26
+
27
+ # register the service
28
+ run "uberspace-setup-service #{daemon_service} ~/bin/#{daemon_service}"
29
+
30
+ end # task :create_service
31
+
32
+ task :create_service_thin do
33
+ # script to start thin
34
+ script = <<-EOF
35
+ #!/bin/bash
36
+ export HOME=/home/#{user}
37
+ source $HOME/.bash_profile
38
+ cd #{deploy_dir}
39
+ exec /home/#{user}/.gem/ruby/#{ruby_version}/bin/bundle exec thin start -p #{daemon_port} -e production 2>&1
40
+ EOF
41
+
42
+ # upload the run script
43
+ put script, "/home/#{user}/bin/#{daemon_service}"
44
+ run "chmod 755 /home/#{user}/bin/#{daemon_service}"
45
+
46
+ end # task :create_service_thin
47
+
48
+ task :create_service_unicorn do
49
+ # script to start unicorn
50
+ script = <<-EOF
51
+ #!/bin/bash
52
+ export HOME=/home/#{user}
53
+ source $HOME/.bash_profile
54
+ cd #{deploy_dir}
55
+ exec /home/#{user}/.gem/ruby/#{ruby_version}/bin/bundle exec unicorn -p #{daemon_port} -c ./config/unicorn.rb -E #{environment} 2>&1
56
+ EOF
57
+
58
+ # upload the run script
59
+ put script, "/home/#{user}/bin/#{daemon_service}"
60
+ run "chmod 755 /home/#{user}/bin/#{daemon_service}"
61
+
62
+ # script to configure unicorn
63
+ unicorn_rb = <<-EOF
64
+ # config/unicorn.rb
65
+ worker_processes 3
66
+ timeout 15
67
+ preload_app true
68
+
69
+ before_fork do |server, worker|
70
+ Signal.trap 'TERM' do
71
+ puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
72
+ Process.kill 'QUIT', Process.pid
73
+ end
74
+
75
+ defined?(ActiveRecord::Base) and
76
+ ActiveRecord::Base.connection.disconnect!
77
+ end
78
+
79
+ after_fork do |server, worker|
80
+ Signal.trap 'TERM' do
81
+ puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
82
+ end
83
+
84
+ defined?(ActiveRecord::Base) and
85
+ ActiveRecord::Base.establish_connection
86
+ end
87
+ EOF
88
+
89
+ # upload the unicorn config file, if it does not exist
90
+ put unicorn_rb, "#{deploy_dir}/config/unicorn.rb" unless file_exists? "#{deploy_dir}/config/unicorn.rb"
91
+
92
+ end # task :create_service_unicorn
93
+
94
+ desc "Remove the service"
95
+ task :remove do
96
+ script = <<-EOF
97
+ cd ~/service/#{daemon_service}
98
+ rm ~/service/#{daemon_service}
99
+ svc -dx . log
100
+ rm -rf ~/etc/run-#{daemon_service}
101
+ EOF
102
+
103
+ unless not file_exists? "~/etc/run-#{daemon_service}"
104
+ # upload script
105
+ put script, "/home/#{user}/rm-#{daemon_service}"
106
+ run "chmod 755 /home/#{user}/rm-#{daemon_service}"
107
+
108
+ # remove the service
109
+ run ". ~/rm-#{daemon_service}"
110
+
111
+ # cleanup
112
+ run "rm /home/#{user}/rm-#{daemon_service}"
113
+ end
114
+
115
+ end # task :remove
116
+
117
+ end
118
+ end
@@ -0,0 +1,61 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+ require 'ratchetify/ruby'
7
+
8
+ desc "Prepare a new uberspace for deployment"
9
+ namespace :setup do
10
+
11
+ desc "Prepare an uberspace for deployment"
12
+ task :default do
13
+ environment
14
+ end
15
+
16
+ desc "Create dirs, configure ruby, activate daemontools, ..."
17
+ task :environment do
18
+
19
+ unless file_exists? '.ratchet'
20
+
21
+ puts "Initializing uberspace '#{user}'"
22
+
23
+ # save the current .bashrc
24
+ run "cp .bashrc bashrc.bak"
25
+
26
+ # create the necessary folders
27
+ create_dir deploy_root unless dir_exists? deploy_root
28
+ create_dir conf_dir unless dir_exists? conf_dir
29
+ run "ln -s #{deploy_root} apps"
30
+
31
+ # dummy main
32
+ create_dir "#{deploy_root}/main"
33
+
34
+ # remove default html and symbolic link
35
+ run "rm -rf #{webroot_dir}/html"
36
+ run "rm -rf /home/#{user}/html"
37
+
38
+ # enable ruby
39
+ ruby
40
+ # activate the daemontools
41
+ run "uberspace-setup-svscan" unless dir_exists? 'service'
42
+
43
+ # done
44
+ run "touch .ratchet"
45
+ end
46
+ end # task :environment
47
+
48
+ desc "Cleans the uberspace, removes (most) changes, restores the uberspace as much as possible"
49
+ task :restore do
50
+ run "mv bashrc.bak .bashrc"
51
+ run "rm -rf .gem .gemrc .ratchet"
52
+
53
+ # restore old html folder etc
54
+ create_dir "#{webroot_dir}/html"
55
+ run "ln -s #{webroot_dir}/html html/"
56
+
57
+ # keep ./apps and ./aconf for now ...
58
+ end # task :clean
59
+
60
+ end # namespace
61
+ end
@@ -0,0 +1,31 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+ require 'ratchetify/service'
7
+
8
+ before "undeploy", "service:remove"
9
+
10
+ desc "Undeploy an app from uberspace"
11
+ namespace :undeploy do
12
+
13
+ desc "Undeploy an app from uberspace"
14
+ task :default do
15
+ drop_database
16
+ remove_repo
17
+ end
18
+
19
+ task :drop_database do
20
+ mysql_database = "#{user}_#{application}" # 'application' MUST NOT contain any '-' !!!
21
+ run "mysql -e 'DROP DATABASE IF EXISTS #{mysql_database};'"
22
+ end
23
+
24
+ task :remove_repo do
25
+ run "cd #{deploy_root} && rm -rf #{fetch :application}"
26
+ run "cd #{webroot_dir} && rm -rf #{fetch :host}.#{fetch :domain}"
27
+ run "cd #{webroot_dir} && rm -rf #{fetch :domain}" unless (wildcard_domain == false)
28
+ end
29
+
30
+ end # namespace
31
+ end
@@ -0,0 +1,46 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+ require 'ratchetify/service'
7
+
8
+ before :update, "service:stop"
9
+ after :update, "service:start"
10
+
11
+ desc "Tasks to update an app"
12
+ namespace :update do
13
+
14
+ desc "Stop the service, update the app then restart"
15
+ task :default do
16
+ # switch to the specified branch
17
+ run "cd #{deploy_dir} && git checkout -b #{fetch :branch}" unless on_branch? deploy_dir, "#{fetch :branch}"
18
+
19
+ # update the repo
20
+ git_cmd = "cd #{deploy_dir} && git pull origin #{fetch :branch}"
21
+
22
+ run git_cmd do |channel, stream, out|
23
+ if out =~ /Password:/
24
+ channel.send_data("#{fetch :repo_password}\n")
25
+ else
26
+ puts out
27
+ end
28
+ end
29
+
30
+ #
31
+ # typical RAILS stuff to finalize
32
+ #
33
+
34
+ # run bundle install first
35
+ run "cd #{deploy_dir} && bundle install --path ~/.gem"
36
+
37
+ # run rake db:migrate to create all tables etc
38
+ run "cd #{deploy_dir} && bundle exec rake db:migrate RAILS_ENV=#{fetch :environment}"
39
+
40
+ # compile assets from the asset pipeline
41
+ run "cd #{deploy_dir} && bundle exec rake assets:precompile RAILS_ENV=#{fetch :environment}"
42
+
43
+ end # end task :default
44
+
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Ratchetify
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,79 @@
1
+
2
+ Capistrano::Configuration.instance.load do
3
+
4
+ require 'capistrano'
5
+ require 'ratchetify/helpers'
6
+ require 'ratchetify/setup'
7
+ require 'ratchetify/domain'
8
+
9
+ before "create:wordpress", "setup:environment"
10
+ after "create:wordpress", "domain:add"
11
+
12
+ desc "Deploy an app for the first time"
13
+ namespace :create do
14
+
15
+ desc "Deploy an wordpress blog to uberspace"
16
+ task :wordpress do
17
+ create_web_dir
18
+ create_database
19
+ finalize
20
+ end
21
+
22
+
23
+ task :create_web_dir do
24
+ # download the worpress .tar
25
+ unless dir_exists? deploy_dir
26
+ # download wp and unpack it
27
+ run "cd #{webroot_dir} && curl -O https://s3-eu-west-1.amazonaws.com/ratchetp/wordpress-3.8.1.tar.gz"
28
+ #run "cd #{deploy_root} && mkdir wp_tmp"
29
+ run "cd #{webroot_dir} && tar xfz wordpress* -C #{deploy_root}"
30
+ run "cd #{deploy_root} && mv wordpress #{application}"
31
+
32
+ # cleanup
33
+ #run "cd #{deploy_root} && rm wordpress*"
34
+ run "cd #{webroot_dir} && rm -rf wordpress*"
35
+
36
+ # rename word press to -> :application
37
+ #run "cd #{deploy_root} && mv ./wordpress #{application}"
38
+ end
39
+
40
+ end # task :create_dir
41
+
42
+ task :create_database do
43
+
44
+ # extract user & password
45
+ my_cnf = capture('cat ~/.my.cnf')
46
+
47
+ my_cnf.match(/^user=(\w+)/)
48
+ mysql_user = $1
49
+ my_cnf.match(/^password=(\w+)/)
50
+ mysql_pwd = $1
51
+ my_cnf.match(/^port=(\w+)/)
52
+ mysql_port = $1
53
+
54
+ # create the database
55
+ mysql_database = "#{user}_#{application}" # 'application' MUST NOT contain any '-' !!!
56
+ run "mysql -e 'CREATE DATABASE IF NOT EXISTS #{mysql_database} CHARACTER SET utf8 COLLATE utf8_general_ci;'"
57
+
58
+ database_yml = <<-EOF
59
+ database: #{mysql_database}
60
+ username: #{mysql_user}
61
+ password: #{mysql_pwd}
62
+ host: localhost
63
+ port: #{mysql_port}
64
+
65
+ EOF
66
+
67
+ # upload the database.yml file
68
+ put database_yml, "#{deploy_dir}/database.yml"
69
+
70
+ end # task :create_database
71
+
72
+ task :finalize do
73
+ # create symbolic links..
74
+ run "cd #{webroot_dir} && ln -s #{deploy_dir} #{fetch :host}.#{fetch :domain}"
75
+ run "cd #{webroot_dir} && ln -s #{deploy_dir} #{fetch :domain}" unless (wildcard_domain == false)
76
+ end # task :finalize
77
+
78
+ end # namespace
79
+ end
data/lib/ratchetify.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'ratchetify/version'
2
+
3
+ Capistrano::Configuration.instance.load do
4
+
5
+ require 'capistrano'
6
+ require 'ratchetify/helpers'
7
+ require 'ratchetify/setup'
8
+ require 'ratchetify/ruby'
9
+ require 'ratchetify/service'
10
+ require 'ratchetify/undeploy'
11
+ require 'ratchetify/domain'
12
+ require 'ratchetify/rails'
13
+ require 'ratchetify/wordpress'
14
+ require 'ratchetify/update'
15
+ require 'ratchetify/help' # monkey patched from capistrano
16
+
17
+ # host and domain for the new app
18
+ set :domain, nil
19
+ set :host, nil
20
+ set :wildcard_domain, false
21
+
22
+ # random port used for the reverse proxy
23
+ set :daemon_port, rand(61000-32768+1)+32768 # random port
24
+ set :type, :rails # supported types are: :rails, :wordpress,
25
+
26
+ # internal variables, should not be changed in the cap file
27
+ set :ruby_version, "2.0.0"
28
+ set :environment, 'production'
29
+ set :is_main, false
30
+
31
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ratchetify/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Michael Kuehl"]
6
+ gem.license = 'MIT'
7
+ gem.email = ["michael@ratchet.cc"]
8
+ gem.description = %q{Deploy Rails apps on Uberspace}
9
+ gem.summary = %q{Ratchetify helps you deploy a Ruby on Rails app on uberspace.de, a popular German shared hosting provider.}
10
+ gem.homepage = "https://github.com/ratchetcc/ratchetify"
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "ratchetify"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = Ratchetify::VERSION
18
+
19
+ # dependencies for capistrano
20
+ gem.add_dependency 'capistrano', '2.12.0'
21
+
22
+ # dependency for mysql on Uberspace
23
+ gem.add_dependency 'mysql2', '>=0.3.11'
24
+
25
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ratchetify
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Kuehl
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.12.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.12.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: mysql2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.11
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.11
41
+ description: Deploy Rails apps on Uberspace
42
+ email:
43
+ - michael@ratchet.cc
44
+ executables:
45
+ - rat
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Capfile.example
51
+ - Gemfile
52
+ - LICENSE
53
+ - README.md
54
+ - Rakefile
55
+ - bin/rat
56
+ - lib/ratchetify.rb
57
+ - lib/ratchetify/base.rb
58
+ - lib/ratchetify/domain.rb
59
+ - lib/ratchetify/help.rb
60
+ - lib/ratchetify/helpers.rb
61
+ - lib/ratchetify/rails.rb
62
+ - lib/ratchetify/ruby.rb
63
+ - lib/ratchetify/service.rb
64
+ - lib/ratchetify/setup.rb
65
+ - lib/ratchetify/undeploy.rb
66
+ - lib/ratchetify/update.rb
67
+ - lib/ratchetify/version.rb
68
+ - lib/ratchetify/wordpress.rb
69
+ - ratchetify.gemspec
70
+ homepage: https://github.com/ratchetcc/ratchetify
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.2.2
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Ratchetify helps you deploy a Ruby on Rails app on uberspace.de, a popular
94
+ German shared hosting provider.
95
+ test_files: []