diff options
-rw-r--r-- | Capfile | 4 | ||||
-rw-r--r-- | Gemfile | 3 | ||||
-rw-r--r-- | Gemfile.lock | 15 | ||||
-rw-r--r-- | config/.gitignore | 17 | ||||
-rw-r--r-- | config/deploy.rb | 69 | ||||
-rw-r--r-- | config/deploy.yml.example | 13 | ||||
-rw-r--r-- | doc/DEPLOY.md | 41 |
7 files changed, 153 insertions, 9 deletions
diff --git a/Capfile b/Capfile new file mode 100644 index 000000000..6a798eb2b --- /dev/null +++ b/Capfile @@ -0,0 +1,4 @@ +load 'deploy' +# Uncomment if you are using Rails' asset pipeline + # load 'deploy/assets' +load 'config/deploy' # remove this line to skip loading any of the default tasks
\ No newline at end of file @@ -1,5 +1,5 @@ # Work around bug in Debian Squeeze - see https://github.com/mysociety/alaveteli/pull/297#issuecomment-4101012 -if File.exist? "/etc/debian_version" and File.open("/etc/debian_version").read.strip =~ /^(squeeze|6\.0\.[45])$/ +if File.exist? "/etc/debian_version" and File.open("/etc/debian_version").read.strip =~ /^(squeeze.*|6\.0\.[45])$/ if File.exist? "/lib/libuuid.so.1" require 'dl' DL::dlopen('/lib/libuuid.so.1') @@ -35,6 +35,7 @@ gem 'will_paginate', '~> 2.3.11' gem 'xapian-full-alaveteli', '~> 1.2.9.5' gem 'xml-simple' gem 'zip' +gem 'capistrano' group :test do gem 'fakeweb' diff --git a/Gemfile.lock b/Gemfile.lock index 0d9d5cc1d..2a15e1bae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,11 +19,18 @@ GEM activesupport (= 2.3.14) activesupport (2.3.14) annotate (2.4.0) + capistrano (2.13.3) + highline + net-scp (>= 1.0.0) + net-sftp (>= 2.0.0) + net-ssh (>= 2.0.14) + net-ssh-gateway (>= 1.1.0) columnize (0.3.6) fakeweb (1.3.0) fast_gettext (0.6.8) gettext (2.2.1) locale + highline (1.6.13) json (1.5.4) linecache (0.46) rbx-require-relative (> 0.0.4) @@ -32,6 +39,13 @@ GEM memcache-client (1.8.5) net-http-local (0.1.2) net-purge (0.1.0) + net-scp (1.0.4) + net-ssh (>= 1.99.1) + net-sftp (2.0.5) + net-ssh (>= 2.0.9) + net-ssh (2.5.2) + net-ssh-gateway (1.1.0) + net-ssh (>= 1.99.1) pg (0.13.2) rack (1.1.3) rails (2.3.14) @@ -72,6 +86,7 @@ PLATFORMS DEPENDENCIES annotate + capistrano fakeweb fast_gettext (>= 0.6.0) gettext (>= 1.9.3) diff --git a/config/.gitignore b/config/.gitignore index 28efb03ec..78d586ea8 100644 --- a/config/.gitignore +++ b/config/.gitignore @@ -1,8 +1,9 @@ -/config.tmp -/general -/general.yml -/database.yml -/rails_env.rb -/logrotate -/memcached.yml -/*.deployed +config.tmp +general +general.yml +database.yml +rails_env.rb +logrotate +memcached.yml +*.deployed +deploy.yml diff --git a/config/deploy.rb b/config/deploy.rb new file mode 100644 index 000000000..888710f83 --- /dev/null +++ b/config/deploy.rb @@ -0,0 +1,69 @@ +require 'bundler/capistrano' + +set :stage, 'staging' unless exists? :stage + +configuration = YAML.load_file('config/deploy.yml')[stage] + +set :application, 'alaveteli' +set :scm, :git +set :deploy_via, :remote_cache +set :repository, configuration['repository'] +set :branch, configuration['branch'] +set :git_enable_submodules, true +set :deploy_to, configuration['deploy_to'] +set :user, configuration['user'] +set :use_sudo, false + +server configuration['server'], :app, :web, :db, :primary => true + +namespace :rake do + namespace :themes do + task :install do + run "cd #{release_path} && bundle exec rake themes:install RAILS_ENV=#{rails_env}" + end + end +end + +# Not in the rake namespace because we're also specifying app-specific arguments here +namespace :xapian do + desc 'Rebuilds the Xapian index as per the ./scripts/rebuild-xapian-index script' + task :rebuild_index do + run "cd #{current_path} && bundle exec rake xapian:rebuild_index models='PublicBody User InfoRequestEvent' RAILS_ENV=#{rails_env}" + end +end + +namespace :deploy do + desc "Restarting mod_rails with restart.txt" + task :restart, :roles => :app, :except => { :no_release => true } do + run "touch #{current_path}/tmp/restart.txt" + end + + [:start, :stop].each do |t| + desc "#{t} task is a no-op with mod_rails" + task t, :roles => :app do ; end + end + + desc 'Link configuration after a code update' + task :symlink_configuration do + links = { + "#{release_path}/config/database.yml" => "#{shared_path}/database.yml", + "#{release_path}/config/general.yml" => "#{shared_path}/general.yml", + "#{release_path}/files" => "#{shared_path}/files", + "#{release_path}/cache" => "#{shared_path}/cache", + "#{release_path}/vendor/plugins/acts_as_xapian/xapiandbs" => "#{shared_path}/xapiandbs", + "#{release_path}/public/download" => "#{release_path}/cache/zips/download" + } + + # "ln -sf <a> <b>" creates a symbolic link but deletes <b> if it already exists + run links.map {|a| "ln -sf #{a.last} #{a.first}"}.join(";") + end + + after 'deploy:setup' do + run "mkdir -p #{shared_path}/files" + run "mkdir -p #{shared_path}/cache" + run "mkdir -p #{shared_path}/xapiandbs" + end +end + +after 'deploy:update_code', 'deploy:symlink_configuration' +after 'deploy:update_code', 'rake:themes:install' diff --git a/config/deploy.yml.example b/config/deploy.yml.example new file mode 100644 index 000000000..aea045dff --- /dev/null +++ b/config/deploy.yml.example @@ -0,0 +1,13 @@ +# Site-specific deployment configuration lives in this file +production: + repository: git://github.com:mysociety/alaveteli.git + branch: master + server: www.example.com + user: deploy + deploy_to: /srv/www/alaveteli_production +staging: + repository: git://github.com:mysociety/alaveteli.git + branch: develop + server: test.example.com + user: deploy + deploy_to: /srv/www/alaveteli_staging diff --git a/doc/DEPLOY.md b/doc/DEPLOY.md new file mode 100644 index 000000000..adeb0e113 --- /dev/null +++ b/doc/DEPLOY.md @@ -0,0 +1,41 @@ +# Deployment + +mySociety uses a custom deployment and buildout system however Capistrano is included as part of Alaveteli as a standard deployment system. + +## Capistrano + +### Set up + +First you need to customise your deployment settings, e.g. the name of the server you're deploying to. This is done by copying the example file `config/deploy.yml.example` to `config/deploy.yml` and editing the settings to suit you. + +TODO: The following instructions could be greatly improved + +These are the general steps required to get your staging server up and running: + +* Install packages from `config/packages` +* Install Postgres and configure a user +* Create a directory to deploy to and make sure your deployment user can write to it +* Run `cap deploy:setup` to create directories, etc. +* Run `cap deploy:update_code` so that we've got a copy of the example config on the server. This process will take a long time installing gems, etc. it will also fail on `rake:themes:install` but that's OK +* SSH to the server, change to the `deploy_to` directory +* `cp releases/[SOME_DATE]/config/general.yml-example shared/general.yml` +* `cp releases/[SOME_DATE]/config/general.yml-example shared/general.yml` +* Edit those files to match your required settings +* Back on your machine run `cap deploy` and it should successfully deploy +* Run the DB migrations `cap deploy:migrate` +* Build the Xapian DB `cap xapian:rebuild_index` +* Configure Apache/Passenger with a DocumentRoot of `your_deploy_to/current/public` +* Phew. Time to admire your work by browsing to the server! + +### Usage + +Ensure you've got a `config/deploy.yml` file with the correct settings for your site. You'll need to share this with everyone in your team that deploys so it might be a good idea to keep the latest version in a [Gist](http://gist.github.com/). + +To deploy to staging just run `cap deploy` but if you want to deploy to production you need to run `cap -S stage=production deploy`. + +For additional usage instructions, see the [Capistrano wiki](https://github.com/capistrano/capistrano/wiki/). + +### TODO + +* Get `cap deploy:setup` to do most of the work described above in the *Set up* section +* Use [Whenever](https://github.com/javan/whenever) to set up cronjobs |