app-deployer 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGIzNjE1OWIyOGZmNWI0YjFkNmQ5ZDk3ODI4NWRhNmExYzUxNDVkYQ==
5
+ data.tar.gz: !binary |-
6
+ ZTI1OGNlYWJjMzhhZjAxMjMwZDNhOGQ1MzU5ZjQ0NmE5ZTNjZTBlMQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YjY1OWQ0OGIxNWExZmM1ZmE0NjA2NTdmNmJkNGQzNWQ1ZDQyOGNjOGUwMDI2
10
+ MzRhYjU0M2RmNTMxZGRlODhlYTE0ZmQ3YzZiMzcyODkwODQyN2M2NGUzYzZj
11
+ ZWVhZWUxNzgwMjQxNjUzNWY1OTcwM2M4ZGZhMDA0NDFkNjc5YjM=
12
+ data.tar.gz: !binary |-
13
+ NGEwYmFjNDQ2ODY5Y2Y0Y2Q0MzE0YmEyNzNmNjE3MmQzMDQ0MWVlZTE2OTg3
14
+ ZjZjN2YxYWU1ZTA3ZDExOWQzYTM0MGVlNTVjYmQzNmQ3YThjMWFhYjBmMmNk
15
+ MmEwODc0OWRkMDA4NmZjOTE0ZGRjZDFhMzJiZGUxZGQzOWM4Yjg=
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in deployer.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ricky Dunlop
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.
@@ -0,0 +1,174 @@
1
+ # App Deployer
2
+
3
+ This gem makes it easy to deploy non rails apps/sites, it also comes with some useful helper tasks for frameworks like lithium and cakephp.
4
+
5
+ It is used by rehabstudio for almost every deployment we do.
6
+
7
+ ## Installation
8
+ **Please be aware that this gem is in active development and some features may not work as expected.**
9
+
10
+ If you find any issues/bugs please add them to the issue tracker, or even better, see the Contributing section at the bottom.
11
+
12
+ ####Required Gems
13
+ We need to ensure we have the following gems installed
14
+
15
+ $ gem install bundler capistrano
16
+
17
+
18
+ ####To install locally:
19
+
20
+ 1. clone the repo
21
+ 2. cd to the directory
22
+ 3. Run `rake install`
23
+
24
+ ---
25
+
26
+ When it is available from rubygems.org you will be able to install it yourself as:
27
+
28
+ $ gem install app-deployer
29
+
30
+ ## Usage
31
+
32
+ ####Basic deployment
33
+
34
+ Open your application's Capfile and make it look like this:
35
+
36
+ require 'rubygems'
37
+ require 'app-deployer'
38
+
39
+ Open your config/deploy.rb file and add this:
40
+
41
+ set :application, 'myapp'
42
+ set :user, "your-deploy-user"
43
+ set :repository, "https://path-to git-repo.git"
44
+ set :deploy_to, "/var/www/myapp"
45
+
46
+ server "http://yourserver.com", :web, :app
47
+
48
+
49
+ ####Multistage
50
+ You can also set this up to use capistrano's multistage extension. This is great if you have to deploy the app to multiple servers like dev, staging etc.
51
+
52
+ To use multistage you should also add the following to your Capfile:
53
+
54
+ require 'capistrano/ext/multistage'
55
+ set :stages, %w(development, staging, production)
56
+ set :default_stage, "production"
57
+
58
+ The setup of your deploy scripts will also change, instead of having config/deploy.rb you need to create a folder called deploy in your config folder and also separate file for each stage.
59
+
60
+ You will need a file for each item in the stages variable in your Capfile.
61
+
62
+ So in this example we would need development.rb, staging.rb and production.rb to be located in the config/deploy directory.
63
+
64
+
65
+ ###Initial setup
66
+ To setup your app you need to run
67
+
68
+ cap deploy:setup
69
+
70
+ or if you are using multistage you would use this (subsituting <stage> with the stage name)
71
+
72
+ cap <stage> deploy:setup
73
+
74
+ This will create the necessary folder structure for deployment
75
+
76
+ ###Deploying
77
+ To deploy your app you can now run
78
+
79
+ cap deploy
80
+
81
+ or for multistage
82
+
83
+ cap <stage> deploy
84
+
85
+
86
+ ##Framework tasks
87
+ To use the extra tasks that are available for frameworks you need to include the file at the bottom of your deploy file.
88
+
89
+
90
+ ###CakePHP
91
+ A lot of the tasks are based on the capcake gem but some have been slightly modified.
92
+ To use the CakePHP tasks, add the following at the bottom of your deploy file:
93
+
94
+ require 'app-deployer/framework/cakephp/cakephp'
95
+
96
+ This will add in some hooks to the deployment process.
97
+
98
+ ####Setup
99
+ On initial setup of your site a DB config file will be generated for you. Just fill in the values at the prompt
100
+
101
+ The tmp folders and any shared folders will also be setup. See Shared folders below for more info on these.
102
+
103
+
104
+ ####After deploy hooks
105
+ Each time you deploy, symlinks for the database file and any shared folders will be created for your app.
106
+
107
+ The tmp cache will also be cleared.
108
+
109
+ ####Changing the CakePHP repo and branch
110
+ Use these lines below to change your repo/branch
111
+
112
+ set :cakephp_repo, "git://github.com/cakephp/cakephp.git"
113
+ set :cake_branch, "origin/2.2"
114
+
115
+
116
+ ####Shared folders
117
+ If you have an uploads folder that you want to preserve on each deploy you can declare them using:
118
+
119
+ set :shared_app_dirs, ["webroot/uploads"]
120
+
121
+ Each time you deploy these folders will be symlinked to the current directory.
122
+ These folders will also be created on deploy:setup to save you creating them manually
123
+
124
+ ####Older version support
125
+ If you are still using CakePHP 1.3 you will need to set the following in your deploy file.
126
+
127
+ set: cakephp_version, 1.3
128
+
129
+ ###Lithium
130
+ First we need to include the lithium tasks in our deploy file
131
+
132
+ require 'app-deployer/framework/lithium/lithium'
133
+
134
+
135
+ ###EC2
136
+ If you use Amazon EC2, you can add this line to make capistrano use your pem file
137
+
138
+ ssh_options[:keys] = ["#{ENV['HOME']}/.ssh/your-key.pem"]
139
+
140
+
141
+ ##Servers
142
+ ###Apache
143
+ To use any of the apache tasks you need to include the file in your deploy script
144
+
145
+ require 'app-deployer/server/apache/apache'
146
+
147
+ To put your server into maintenance mode run:
148
+
149
+ cap apache:maintenance:start
150
+
151
+ To take it out of maintenance mode run:
152
+
153
+ cap apache:maintenance:end
154
+
155
+ ###Nginx
156
+ To be completed
157
+
158
+ ###PHP5-FPM
159
+ You can automatically reload the php-fpm service after a deploy by including the task at the bottom of your deploy file
160
+
161
+ require 'app-deployer/server/php-fpm'
162
+
163
+
164
+ You should ensure the deploy user has the correct privileges to do this by adding a line to the sudoers file using visudo
165
+
166
+ deploy ALL=(ALL) NOPASSWD: /usr/sbin/service php5-fpm reload
167
+
168
+ ## Contributing
169
+
170
+ 1. Fork it
171
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
172
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
173
+ 4. Push to the branch (`git push origin my-new-feature`)
174
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/app-deployer/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ricky Dunlop"]
6
+ gem.email = ["ricky@rehabstudio.com"]
7
+ gem.description = %q{Features a modular design allowing it to be extended for various frameworks. Includes recipes for CakePHP, Lithium, MySQL, Nginx, Apache. Uses Railsless deploy}
8
+ gem.summary = %q{Deploy PHP apps using Capistrano}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.add_dependency 'capistrano', ">= 2.13.5"
15
+ gem.add_dependency 'colored', ">= 1.2.0"
16
+ gem.name = "app-deployer"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = App::Deployer::VERSION
19
+ end
@@ -0,0 +1,11 @@
1
+ require "app-deployer/version"
2
+ require 'app-deployer/helpers'
3
+ require 'app-deployer/railsless-deploy'
4
+ require 'app-deployer/composer'
5
+ require 'app-deployer/compass'
6
+ require 'colored'
7
+
8
+ module App
9
+ module Deployer
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :compass do
3
+ desc 'Compiles Compass files into stylsheets'
4
+ task :compile do
5
+ run("cd #{latest_release}/webroot; compass compile --output-style nested --force -e production")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,68 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :composer do
3
+ desc "Gets composer and installs it"
4
+ task :get, :roles => :app, :except => { :no_release => true } do
5
+ if remote_file_exists?("#{previous_release}/composer.phar")
6
+ pretty_print "--> Copying Composer from previous release"
7
+ run "#{try_sudo} sh -c 'cp #{previous_release}/composer.phar #{latest_release}/'"
8
+ puts_ok
9
+ end
10
+
11
+ if !remote_file_exists?("#{latest_release}/composer.phar")
12
+ pretty_print "--> Downloading Composer"
13
+
14
+ run "#{try_sudo} sh -c 'cd #{latest_release} && curl #{curl_options} -sS http://getcomposer.org/installer | #{php_bin}'"
15
+ else
16
+ pretty_print "--> Updating Composer"
17
+
18
+ run "#{try_sudo} sh -c 'cd #{latest_release} && #{php_bin} composer.phar self-update'"
19
+ end
20
+ puts_ok
21
+ end
22
+
23
+ desc "Updates composer"
24
+
25
+ desc "Runs composer to install vendors from composer.lock file"
26
+ task :install, :roles => :app, :except => { :no_release => true } do
27
+ if !composer_bin
28
+ composer.get
29
+ set :composer_bin, "#{php_bin} composer.phar"
30
+ end
31
+
32
+ pretty_print "--> Installing Composer dependencies"
33
+ run "#{try_sudo} sh -c 'cd #{latest_release} && #{composer_bin} install #{composer_options}'"
34
+ puts_ok
35
+ end
36
+
37
+ desc "Runs composer to update vendors, and composer.lock file"
38
+ task :update, :roles => :app, :except => { :no_release => true } do
39
+ if !composer_bin
40
+ composer.get
41
+ set :composer_bin, "#{php_bin} composer.phar"
42
+ end
43
+
44
+ pretty_print "--> Updating Composer dependencies"
45
+ run "#{try_sudo} sh -c 'cd #{latest_release} && #{composer_bin} update #{composer_options}'"
46
+ puts_ok
47
+ end
48
+
49
+ desc "Dumps an optimized autoloader"
50
+ task :dump_autoload, :roles => :app, :except => { :no_release => true } do
51
+ if !composer_bin
52
+ composer.get
53
+ set :composer_bin, "#{php_bin} composer.phar"
54
+ end
55
+
56
+ pretty_print "--> Dumping an optimized autoloader"
57
+ run "#{try_sudo} sh -c 'cd #{latest_release} && #{composer_bin} dump-autoload --optimize'"
58
+ puts_ok
59
+ end
60
+
61
+ task :copy_vendors, :roles => :app, :except => { :no_release => true } do
62
+ pretty_print "--> Copying vendors from previous release"
63
+
64
+ run "vendorDir=#{current_path}/libraries; if [ -d $vendorDir ] || [ -h $vendorDir ]; then cp -a $vendorDir #{latest_release}/libraries; fi;"
65
+ puts_ok
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,215 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ require 'erb'
4
+
5
+ # =========================================================================
6
+ # Settings
7
+ # =========================================================================
8
+
9
+ _cset :shared_app_dirs, []
10
+ _cset(:cakephp_branch) { "master" }
11
+ _cset(:cakephp_repo) { "https://github.com/cakephp/cakephp.git" }
12
+ _cset :cakephp_version, 2
13
+ _cset :tmp_children, %w(cache logs sessions tests)
14
+ _cset :cache_children, %w(models persistent views)
15
+ _cset :logs_files, %w(debug error)
16
+ _cset(:tmp_path) { File.join(shared_path, "tmp") }
17
+ _cset(:cache_path) { File.join(tmp_path, "cache") }
18
+ _cset(:logs_path) { File.join(tmp_path, "logs") }
19
+ if cakephp_version >= 2
20
+ set :shared_children, %w(Config tmp)
21
+ set :database_partial_path, "Config/database.php"
22
+ else
23
+ set :shared_children, %w(config tmp)
24
+ set :database_partial_path, "config/database.php"
25
+ end
26
+ set(:database_path) { File.join(shared_path, database_partial_path) }
27
+
28
+ # =========================================================================
29
+ # Hooks
30
+ # =========================================================================
31
+
32
+ after('deploy:setup', 'cakephp:setup')
33
+ after('deploy:create_symlink', 'cakephp:create_symlink')
34
+
35
+ ["composer:install", "composer:update"].each do |action|
36
+ before action do
37
+ if copy_vendors
38
+ composer.copy_vendors
39
+ end
40
+ end
41
+ end
42
+
43
+ after "deploy:finalize_update" do
44
+ if use_composer
45
+ if update_vendors
46
+ composer.update
47
+ else
48
+ composer.install
49
+ end
50
+ end
51
+ if clear_cache
52
+ cakephp.cache.clear
53
+ end
54
+ end
55
+
56
+ # =========================================================================
57
+ # Tasks
58
+ # =========================================================================
59
+
60
+ namespace :cakephp do
61
+
62
+ desc <<-DESC
63
+ Prepares server for deployment of a CakePHP application. \
64
+
65
+ By default, it will create a shallow clone of the CakePHP repository \
66
+ inside #{shared_path}/cakephp and run deploy:cake:update.
67
+ DESC
68
+ task :setup do
69
+ transaction do
70
+ run "cd #{shared_path} && git clone --depth 1 #{cakephp_repo} cakephp"
71
+ checkout
72
+ shared.setup
73
+ database.config
74
+ end
75
+ end
76
+
77
+ desc <<-DESC
78
+ Checkout a new branch/tag.
79
+ DESC
80
+ task :checkout do
81
+ stream "cd #{shared_path}/cakephp && git checkout -q #{cakephp_branch}"
82
+ end
83
+
84
+ desc <<-DESC
85
+ Update the cake repository to the latest version.
86
+ DESC
87
+ task :update do
88
+ stream "cd #{shared_path}/cakephp && git pull"
89
+ end
90
+
91
+ desc <<-DESC
92
+ This is a task that will get called from the deploy:create_symlink task \
93
+ It runs just before the release is symlinked to the current directory \
94
+
95
+ You should use it to create symlinks to things like your database config \
96
+ and any shared directories or files that your app uses .
97
+ DESC
98
+ task :create_symlink do
99
+ transaction do
100
+ database.create_symlink
101
+ shared.create_symlink
102
+ end
103
+ end
104
+
105
+ # Framework specific tasks
106
+
107
+ # Caching
108
+ namespace :cache do
109
+ desc <<-DESC
110
+ Clears CakePHP's APP/tmp/cache and its sub-directories.
111
+
112
+ Recursively finds all files in :cache_path and runs `rm -f` on each. If a file \
113
+ is renamed/removed after it was found but before it removes it, no error \
114
+ will prompt (-ignore_readdir_race). If symlinks are found, they will not be followed.
115
+
116
+ You will rarely need to call this task directly; instead, use the `deploy' \
117
+ task (which performs a complete deploy, including `cake:cache:clear')
118
+ DESC
119
+ task :clear, :roles => :web, :except => { :no_release => true } do
120
+ run "#{try_sudo} find -P #{cache_path} -ignore_readdir_race -type f -name '*' -exec rm -f {} \\;"
121
+ end
122
+ end
123
+
124
+ # Database config
125
+ namespace :database do
126
+ desc <<-DESC
127
+ Generates CakePHP database configuration file in #{shared_path}/config \
128
+ and symlinks #{current_path}/config/database.php to it
129
+ DESC
130
+ task :config, :roles => :web, :except => { :no_release => true } do
131
+ on_rollback { run "rm -f #{database_path}; true" }
132
+ puts "Database configuration"
133
+ prompt_with_default(:datasource, cakephp_version >= 2 ? "Database/Mysql" : "mysql")
134
+ prompt_with_default(:persistent, 'false')
135
+ prompt_with_default(:host, "localhost")
136
+ prompt_with_default(:login, user)
137
+ set :password, Capistrano::CLI.password_prompt("password:")
138
+ prompt_with_default(:database, "")
139
+ prompt_with_default(:prefix, "")
140
+ prompt_with_default(:encoding, 'utf8')
141
+
142
+ template = File.read(File.join(File.dirname(__FILE__), "templates", "database.php.erb"))
143
+ result = ERB.new(template).result(binding)
144
+
145
+ put(result, "#{database_path}", :mode => 0644, :via => :scp)
146
+ after("deploy:create_symlink", "cakephp:database:create_symlink")
147
+ end
148
+
149
+ desc <<-DESC
150
+ Creates required CakePHP's APP/config/database.php as a symlink to \
151
+ #{deploy_to}/shared/config/database.php
152
+ DESC
153
+ task :create_symlink, :roles => :web, :except => { :no_release => true } do
154
+ run "#{try_sudo} rm -f #{current_path}/#{database_partial_path}"
155
+ run "#{try_sudo} ln -s #{database_path} #{current_path}/#{database_partial_path}"
156
+ end
157
+ end
158
+
159
+ # Shared directories and files
160
+ namespace :shared do
161
+ desc <<-DESC
162
+ Creates shared folders on the server
163
+ DESC
164
+ task :setup do
165
+ dirs = [deploy_to, releases_path, shared_path]
166
+ dirs += shared_children.map { |d| File.join(shared_path, d) }
167
+ tmp_dirs = tmp_children.map { |d| File.join(tmp_path, d) }
168
+ tmp_dirs += cache_children.map { |d| File.join(cache_path, d) }
169
+ run "#{try_sudo} mkdir -p #{(dirs + tmp_dirs).join(' ')}"
170
+ run "#{try_sudo} chmod -R 777 #{tmp_path}" if (!user.empty?)
171
+
172
+ if shared_app_dirs
173
+ shared_app_dirs.each { | link | run "#{try_sudo} mkdir -p #{shared_path}/#{link}" }
174
+ end
175
+ end
176
+
177
+ desc <<-DESC
178
+ Symlinks all files and folders
179
+ DESC
180
+ task :create_symlink do
181
+ run "ln -s #{shared_path}/tmp #{latest_release}/tmp";
182
+ if shared_app_dirs
183
+ shared_app_dirs.each { | link | run "ln -s #{shared_path}/#{link} #{current_path}/#{link}" }
184
+ end
185
+ end
186
+ end
187
+
188
+ # Logs
189
+ namespace :log do
190
+ desc <<-DESC
191
+ Clears CakePHP's APP/tmp/logs and its sub-directories
192
+
193
+ Recursively finds all files in :logs_path and runs `rm -f` on each. If a file \
194
+ is renamed/removed after it was found but before it removes it, no error \
195
+ will prompt (-ignore_readdir_race). If symlinks are found, they will not be followed.
196
+ DESC
197
+ task :clear, :roles => :web, :except => { :no_release => true } do
198
+ run "#{try_sudo} find -P #{logs_path} -ignore_readdir_race -type f -name '*' -exec rm -f {} \\;"
199
+ end
200
+
201
+ desc <<-DESC
202
+ Streams the result of `tail -f` on all :logs_files \
203
+
204
+ By default, the files are `debug` and `error`. You can add your own \
205
+ in config/deploy.rb
206
+
207
+ set :logs_files %w(debug error my_log_file)
208
+ DESC
209
+ task :tail, :roles => :web, :except => { :no_release => true } do
210
+ files = logs_files.map { |d| File.join(logs_path, d) }
211
+ stream "#{try_sudo} tail -f #{files.join(' ')}"
212
+ end
213
+ end
214
+ end
215
+ end