deployment with Capistrano 3 (affects foodcoops#148)

This commit is contained in:
wvengen 2014-01-15 13:51:24 +01:00
parent b2f032ac8e
commit ca234f0b70
5 changed files with 199 additions and 48 deletions

View file

@ -0,0 +1,101 @@
# Capistrano tasks for the initial setup
namespace :deploy do
desc 'Creates and initialises a new foodsoft instance'
task :initial do
before 'deploy:check:linked_files', 'deploy:initial:touch_shared'
before 'deploy:updated', 'deploy:initial:secret_token'
before 'deploy:updated', 'deploy:initial:app_config'
before 'deploy:updated', 'deploy:initial:db:config'
before 'deploy:updated', 'deploy:initial:db:create'
before 'deploy:migrate', 'deploy:initial:db:load'
end
after :initial, :deploy
namespace :initial do
namespace :db do
desc 'Generate new database.yml with random password'
task :config => ['deploy:set_rails_env'] do
require 'securerandom'
on roles(:app), in: :groups do
db_name = fetch(:unique_app_name).gsub(/[^-_a-z0-9]/i, '')
db_passwd = SecureRandom.urlsafe_base64(24).to_s
db_yaml = {
fetch(:rails_env).to_s => {
'adapter' => 'mysql2',
'encoding' => 'utf8',
'database' => db_name,
'username' => db_name,
'password' => db_passwd,
}
}
execute :mkdir, '-p', shared_path.join("config")
upload! StringIO.new(db_yaml.to_yaml), shared_path.join("config/database.yml")
end
end
# assumes mysql access setup (~/.my.cnf), with permissions
desc 'Create database new database'
task :create => ['deploy:set_rails_env'] do
on roles(:app), in: :sequence do
config = capture :cat, shared_path.join("config/database.yml")
config = YAML.load(config)[fetch(:rails_env).to_s]
# http://www.grahambrooks.com/blog/create-mysql-database-with-capistrano/
execute :mysql, "--execute='CREATE DATABASE IF NOT EXISTS `#{config['database']}`';"
execute :mysql, "--execute='GRANT ALL ON `#{config['database']}`.* TO \"#{config['username']}\" IDENTIFIED BY \"#{config['password']}\";'"
end
end
desc 'Load database schema'
task :load => ['deploy:set_rails_env'] do
on roles(:app), in: :groups do
# workaround nonexistent release_path on first deploy
path = releases_path.join(capture(:ls, releases_path).split("\n").sort.last)
within path do
with rails_env: fetch(:rails_env) do
execute :rake, 'db:schema:load'
end
end
end
end
end
desc 'Writes a new secret token'
task :secret_token do
require 'securerandom'
on roles(:app), in: :groups do
secret = SecureRandom.hex(64)
text = "Foodsoft::Application.config.secret_token = \"#{secret}\""
execute :mkdir, '-p', shared_path.join("config/initializers")
upload! StringIO.new(text), shared_path.join("config/initializers/secret_token.rb")
end
end
desc 'Creates a default app_config.yml'
task :app_config do
on roles(:app), in: :groups do
execute :mkdir, '-p', shared_path.join("config")
# workaround nonexistent release_path on first deploy
path = releases_path.join(capture(:ls, releases_path).split("\n").sort.last)
execute :cp, path.join("config/app_config.yml.SAMPLE"), shared_path.join("config/app_config.yml")
end
end
desc 'Touches the shared configuration files (for initial deploy)'
task :touch_shared do
on roles(:app), in: :groups do
execute :mkdir, '-p', shared_path.join("config/initializers")
execute :touch, shared_path.join("config/initializers/secret_token.rb")
execute :touch, shared_path.join("config/app_config.yml")
execute :touch, shared_path.join("config/database.yml")
end
end
end
end

View file

@ -0,0 +1,24 @@
# capistrano-resque could be used, but it does not support running resque as another user.
# If you want to run resque as another user, setup sudo to allow running commands as that user:
# deploy ALL=(foodsoft_user) NOPASSWD: ALL
# and set `:run_user` to the foodsoft user.
namespace :resque do
%w{start stop restart}.each do |action|
desc "#{action.capitalize} Resque workers"
task action => ['deploy:set_rails_env'] do
on roles(:resque), in: :groups do
within current_path do
cmd = command(:rake, "resque:#{action}_workers", "RAILS_ENV=#{fetch(:rails_env)}")
if fetch(:run_user).nil? or fetch(:run_user) == local_user
execute cmd
else
execute 'sudo', '-u', fetch(:run_user), cmd
end
end
end
end
end
end