require 'erb' Rake::Task["deploy:compile_assets"].clear namespace :deploy do desc 'Compile assets' task :compile_assets => [:set_rails_env] do # invoke 'deploy:assets:precompile' invoke 'deploy:assets:precompile_local' invoke 'deploy:assets:backup_manifest' end namespace :assets do desc "Precompile assets locally and then rsync to web servers" task :precompile_local do # compile assets locally run_locally do DB = YAML.load_file('config/database.yml')['development'] db_connection = "#{DB['adapter']}://#{DB['username']}:#{DB['password']}@#{DB['host']}/#{DB['database']}" execute "RAILS_ENV=#{fetch(:stage)} DATABASE_URL=#{db_connection} bundle exec rake assets:precompile" end # rsync to each server local_dir = "./public/assets/" on roles( fetch(:assets_roles, [:web]) ) do # this needs to be done outside run_locally in order for host to exist remote_dir = "#{host.user}@#{host.hostname}:#{release_path}/public/assets/" run_locally { execute "rsync -av --delete #{local_dir} #{remote_dir}" } end # clean up run_locally { execute "rm -rf #{local_dir}" } end end end namespace :load do task :defaults do set :files_public_dirs, ['system'] set :files_private_dirs, [] set :nginx_workers, 1 set :nginx_assets_dirs, %w[assets system] set :nginx_max_body_size, '10m' end end namespace :git do desc 'Update new git repo url' task :update_repo_url do on roles :app do within repo_path do execute :git, 'remote', 'set-url', 'origin', fetch(:repo_url) end end end end namespace :tmp_cache do desc 'Clear file system tmp cache' task :clear do on roles :app do within current_path do with rails_env: fetch(:stage) do execute :rake, 'tmp:cache:clear' end end end end end namespace :files do def send_files(type, server, root = 'public') raise "No server given" if !server system "rsync --progress -rue 'ssh -p #{fetch(:port)}' #{root}/#{type} #{server.user}@#{server.hostname}:#{shared_path}/#{root}/" end def get_files(type, server, root = 'public') raise "No server given" if !server puts "Importing #{type}. Please wait..." system "rsync --progress -rue 'ssh -p #{fetch(:port)}' #{server.user}@#{server.hostname}:#{shared_path}/#{root}/#{type} ./#{root}/" end desc 'Import public files' task :server_to_local do on roles :app do |host| fetch(:files_public_dirs).each do |type| get_files type, host end end end desc 'Export public files' task :local_to_server do on roles :app do |host| fetch(:files_public_dirs).each do |type| send_files type, host end end end namespace :private do desc 'Import private files' task :server_to_local do on roles :app do |host| fetch(:files_private_dirs).each do |type| get_files type, host, 'private' end end end desc 'Export private files' task :local_to_server do on roles :app do |host| fetch(:files_private_dirs).each do |type| send_files type, host, 'private' end end end end end namespace :db do desc "Sync local DB with server DB" task :server_to_local do on roles(:app) do |role| within current_path do with rails_env: fetch(:stage) do execute :rake, 'db:data:dump' end run_locally do execute :rsync, "-avzO -e 'ssh -p #{fetch(:port)}' --exclude='.DS_Store' #{role.user}@#{role.hostname}:#{current_path}/db/data.yml db/data.yml" end end end end desc "Sync server DB with local DB" task :local_to_server do on roles(:app) do |role| run_locally do execute :rsync, "-avzO -e 'ssh -p #{fetch(:port)}' --exclude='.DS_Store' db/data.yml #{role.user}@#{role.hostname}:#{current_path}/db/data.yml" end within current_path do with rails_env: fetch(:stage) do execute :rake, 'db:data:load' end end end end end namespace :nginx do def upload(server, source, destination) File.open(source, 'w') do |f| f.puts ERB.new(File.read("#{source}.erb"), nil, '-').result end system "rsync --rsync-path='sudo rsync' -avzO -e 'ssh -p #{fetch(:port)}' '#{source}' #{fetch(:deployer_name)}@#{server.hostname}:#{destination}" FileUtils.rm_f source end desc 'Export nginx configuration files' task :local_to_server do on roles :app do |host| upload host, 'config/nginx.conf', '/etc/nginx/nginx.conf' upload host, 'config/nginx.app.conf', '/etc/nginx/sites-available/default' end end end