app-deployer 0.0.3

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.
@@ -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