Task to execute migrations after publishing app in Capistrano - ruby-on-rails

There is the following 'deploy.rb' code:
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
end
This code deploys my app and then restarts my server, but there are some pending migrations after deploy. Can I add task to execute migrations automatically after uploading code? Thanks in advance.

Capistrano 2
If you want to run migrations everytime you deploy, add in your deploy.rb :
after "deploy:update_code", "deploy:migrate"
Or instead of modify deploy.rb, you can call cap deploy:migrations, this will run all pending migrations after your deploy
Capistrano 3
I presume you have installed capistano-rails gem.
If you want to run migrations automaticaly you can required in your Capfile
require 'capistrano/rails/migrations'
Or just run cap deploy:migrate
Sources : https://github.com/capistrano/rails#capistranorails and http://www.talkingquickly.co.uk/2014/01/deploying-rails-apps-to-a-vps-with-capistrano-v3/
Hope this helps

Related

Capistrano not restarting nginx

I have setup Capistrano and eveything is working fine except Capistrano is not restarting passenger after deployment. Eveytime after deployment I have to ssh into server and type touch tmp/restart.txt inside current directory. I tried different ways to restart passenger but nothing is working for me.
first attempt:
namespace :deploy do
task :restart do
on roles(:app) do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
end
end
second attempt
namespace :deploy do
task :restart do
on roles(:app) do
within current_path do
execute :touch, 'tmp/restart.txt'
end
end
end
end
third attempt
namespace :deploy do
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
I found above code snippets in stackoverflow with similar problem to mine but none of them is restarting the server.
I am using capistrano (3.4.0) with Rails 4 (nginx + passenger)
It could be that your deploy:restart task is not being executed.
Capistrano 3.1.0 and higher (as explained in the Capistrano's CHANGELOG), does not automatically execute deploy:restart at the end of cap deploy.
You must therefore explicitly tell Capistrano to do so, by adding this to your deploy.rb:
after 'deploy:publishing', 'deploy:restart'

How to get rake output to show in Capistrano

I am running rake tasks on the server using a snippet like the following in the deploy.rb of a rails app.
desc 'Invoke rake task on the server'
task :invoke do
fail 'no task provided' unless ENV['task']
on roles(:app) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :rake, ENV['task']
end
end
end
end
The rake task runs ok but I would like to see the output from the rake task displayed in the console where I run the capistrano task.
puts commands in the rake task do not appear.
If in Debug mode, capistrano prints out the outputs of the commands if I'm not mistaken. Probably you set your log level to :info. Just find the line in your deploy.rb and change it to (add it if its not there):
set :log_level, :debug
If you want to have this only for the single command or I was wrong and the above solution does not work for you, maybe checkout this answer (dunno if its still working):
Capistrano log level
UPDATE: How about using Rails logger instead of puts in the game task:
Rails.logger.debug "test"

Where should I put my deployment tasks when using Capistrano?

I'm using Capistrano to deploy apps that I'm building in Sinatra and Rails. For a while now I've been writing all the stuff I need to get done during the deployment right into config/deploy.rb. It looks like I'm just writing Rake here. I was wondering if I could get some advice on if I'm putting these in the right place or if I could be more "Capistranorish" with my deployments.
Here are a few examples of things I'm doing here. I write pretty much everything that I need my deployments to do here.
# deploy.rb
task :initctl_reload_configuration do
on roles(:app), in: :sequence do
execute "sudo initctl reload-configuration"
end
end
task :rebuild_sitemap_no_ping do
on roles(:app), in: :sequence do
execute "cd /srv/app/#{environment}/current && RAILS_ENV=#{environment} bundle exec rake sitemap:refresh:no_ping"
end
end
task :rebuild_sitemap do
on roles(:app), in: :sequence do
execute "cd /srv/app/#{environment}/current && RAILS_ENV=#{environment} bundle exec rake sitemap:refresh"
end
end
task :restart_services do
on roles(:app), in: :sequence do
execute "sudo service tomcat6 restart"
execute "sudo service sunspot-solr restart"
execute "sudo service app-#{environment} restart"
execute "sudo service nginx restart"
end
end
If that's all you got, it might be just fine leaving it in deploy.rb.
If you really want to move those tasks somewhere, below contents of Capfile (you likely have it in the root of your project) should give you a hint:
# Load custom tasks from `lib/capistrano/tasks' if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
So just create a file in lib/capistrano/tasks/ ending with .rake and that should do it!

cap v3 rails 4 passenger deploy Web application could not be started because Gemfile not found

When we deploy to our server, everything deploys fine, however we get the error "Gemfile not found" right after. At first I thought this was nginx not starting, but if I restart the box, the error goes away and the application works perfectly. We are trying to determine why this is occurring and how to fix it. As of right now, I am not sure where to begin and nothing I seem to research on the "google" has turned up answers.
The breakdown of the server setup and deployment:
rails 4
rbenv
ruby 2.1.0
capistrano v3
passenger
server build with chef
The Capfile:
require 'pry'
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
# Includes tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails/tree/master/assets
# https://github.com/capistrano/rails/tree/master/migrations
#
# require 'capistrano/rvm'
require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
# require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
The deploy.rb:
set :application, 'api'
set :scm, :git
set :repo_url, 'git#github.com:PlacewiseMedia/API.git'
set :branch, 'develop'
set :deploy_to, '/home/apps/api'
set :deploy_via, :remote_cache
set :keep_releases, 10
set :user, 'deploy'
set :use_sudo, false
set :rbenv_type, :system
set :rbenv_ruby, '2.1.0'
set :rbenv_path, '/opt/rbenv'
namespace :deploy do
desc 'Restart application'
task :restart_application do
on roles(:app), in: :sequence, wait: 5 do
spacer("Setting up restart file")
execute "mkdir -p #{release_path}/tmp ; touch #{release_path}/tmp/restart.txt"
spacer("Restarting the nginx service")
execute "sudo service nginx restart"
spacer()
end
end
desc 'Run Migrations'
task :update_database do
on roles(:app), in: :sequence, wait: 5 do
within(release_path) do
with rails_env: fetch(:rails_env) do
spacer("Updating the database")
execute :rake, "db:migrate", "--trace"
spacer()
end
end
end
end
desc 'Create application symlinks'
task :shared_links do
on roles(:app), in: :sequence, wait: 5 do
spacer("Creating application symlinks")
execute "rm #{release_path}/config/database.yml"
execute "ln -s #{shared_path}/config/database.yml #{release_path}/config/database.yml"
execute "ln -s #{shared_path}/config/secrets.yml #{release_path}/config/secrets.yml"
execute "ln -s #{shared_path}/bin/passenger #{release_path}/bin/passenger"
spacer()
end
end
after 'deploy:updated', 'deploy:shared_links'
after :finishing, 'deploy:update_database'
after :finishing, 'deploy:restart_application'
after :finishing, 'deploy:cleanup'
end
namespace :setup do
desc 'Copy the secrets.yml and database.yml files'
task config: ['config/secrets.yml', 'config/database.yml'] do |t|
on roles(:all) do
execute "mkdir -p #{shared_path}/config"
t.prerequisites.each do |file|
upload! file, "#{shared_path}/config"
end
end
end
end
def spacer(desc = nil)
puts "-----------------------------------------------------------------------------"
if desc
puts desc
puts "-----------------------------------------------------------------------------"
end
end
The error:
UPDATE 09/25 : 02:10pm PST
After working with https://hackhands.com/ we discovered that multiple instances of nginx are running as shown:
I can work to kill the services and restart it but it seems like something may not be configured correctly on the server via chef or our cap deployment. If I restart the box things work as stated, but we also tried killing the nginx services. We discovered that works as well. Our dev ops team is working on this, but we are still perplexed how this has occurred or how to repair it.
UPDATE 09/26 : 11:06am PST
I found where the config comes from on the passenger spinup, if you
look in /etc/service/ you will see the folders for the apps that are
on the server. Look at the run file in the folder you're interested
in and you'll see the passenger config. That fires off a ruby .bin/passenger start process, which then fires off the /tmp nginx
process which is hanging on app restart. I've tried restarting all in
different combos, the one that seems to work is killing the nginx
process, then running sudo killall ruby to respawn the new app...
not ideal
So the update our DevOps team did to address this issue revolves around the way passenger spawns nginx. The config that it was using was the older spawn-lv2 from previous versions, and I changed it to spawn for the current version 4. What this seems to do is to stop creating new directories in /tmp that were referenced by the runit script but would fail because the old version was still running. Now it looks like the updates are done in the current /tmp directory instead, so it doesn't matter if the process is still running.
This update was done to the rackbox default attribute in chef: default["rackbox"]["default_config"]["passenger_runit"]["spawn_method"] = "smart"

Exists any library to run rails "migrations" not related to AC in a capistrano deploy?

I'm looking for a library that allows me to run incremental ruby scripts every capistrano deploy (like active record migrations but without a database).
I can't seem to find anything in google.
How about capistrano itself? :)
You can add tasks to run before or after deploy in your deploy.rb file
namespace :deploy do
desc "Do something before deploy."
task :my_awesome_predeploy_task do
# do stuff here...
end
desc "Do something after deploy."
task :my_awesome_postdeploy_task do
# do stuff here...
end
end
namespace :deploy do
before :deploy, "deploy:my_awesome_predeploy_task"
after :deploy, "deploy:my_awesome_postdeploy_task"
end

Resources