capistrano 3 `rake db:migrate` runs anyway - ruby-on-rails

My rails application uses capistrano 3.4.0 for the deploy tasks.
In my Capfile I have the line require 'capistrano/rails/migrations' in order to have the configured task that can run the DB migrations.
When I cap production deploy, I can see always the following output:
INFO [deploy:migrate] Run `rake db:migrate`
DEBUG [6214167f] Running /usr/bin/env if test ! -d XXXX/releases/20160117093811; then echo "Directory does not exist 'XXXX/releases/20160117093811'" 1>&2; false; fi as deploy#candiru-web
DEBUG [6214167f] Command: if test ! -d XXXX/releases/20160117093811; then echo "Directory does not exist 'XXXX/releases/20160117093811'" 1>&2; false; fi
DEBUG [6214167f] Finished in 0.005 seconds with exit status 0 (successful).
INFO [1ebeb8c8] Running ~/.rvm/bin/rvm default do bundle exec rake db:migrate as deploy#candiru-web
DEBUG [1ebeb8c8] Command: cd XXXX/releases/20160117093811 && ( RAILS_ENV=production ~/.rvm/bin/rvm default do bundle exec rake db:migrate )
even if I don't add something like after :deploy, "deploy:migrate".
If I comment out the line require 'capistrano/rails/migrations', the migration won't be executed.
Why? shouldn't it run only if I add the task to my deploy script in config/deploy.rb?

According to documentation of the capistrano/rails gem, you have to set :conditionally_migrate option in order to check if you need to run migrations.
I guess that's the option you need and you should add it in your deploy.rb, this way:
set :conditionally_migrate, true
And to answer your question, in migrations.rake file the task deploy:migrate is already set to run after deploy:updated.
Also, if you want to completely remove this task from your deploy process, and always run migrations manually, by invoking deploy:migrate, you can do like this:
Rake::Task["deploy:migrate"].clear_actions

Related

Running delayed job using bundle exec

In general, I will start the delayed_job using cmd:
RAILS_ENV=production bin/delayed_job start
Now I wrote a simple upstart script to automatically start the delayed job after reboot.
I found that if I wrote the cmd above in the script, it will fail.
# this is the execution in the upstart conf
exec RAILS_ENV=production bin/delayed_job start
After some google and test, I found this would work in my script:
exec bundle exec /usr/bin/env RAILS_ENV=production bin/delayed_job start
This resulted in my question, I guess /usr/bin/env RAILS_ENV=production is to pass the environment variable into the bin/delay_job script, how about bundle exec here?
Without having bundle exec in the script, it will throw error regarding to
require': cannot load such file -- bundler/setup (LoadError).
I realized that using bundle exec helps run rails under some context of the environment, but why is it necessary in the script?
Or is bundle exec necessary when I want to execute cmd like bin/delayed_job or rake in the script?
Thanks.
updated
I copied the upstart script to another node and executed it the same way.
However, it throws the incompatible library version error...
I run
bundle exec /usr/bin/env RAILS_ENV=production bin/delayed_job start
directly on terminal and it worked as expected, but failed when putting the command above in a script.
Could someone tell me why the result differed when executing the same command but in different place?

Rails 'rake task' execute in ‘RAILS_ENV=production' with nohup

I have rake task which continuously need to be active. Whenever I ran it by command
RAILS_ENV=production rake jobs:abc
it works fine but when I close terminal rake job get stopped.So I found other solution on it by using nohup to run it in background.
I execute command:
nohup RAILS_ENV=production rake jobs:work &
but it gives error:
nohup: failed to run command ‘RAILS_ENV=production’: No such file or directory
Please suggest, to way execute rake task in a production environment.
Set the environment variable before the nohup command.
RAILS_ENV=production nohup rake jobs:work
Try this one
nohup rake jobs:work RAILS_ENV=production
I have commented the solution above as well
If you need nohup functionality, you should also consider screen.
RAILS_ENV=production screen -L rake jobs:work
It starts a new terminal which isn't bound to your current session.
To come back to your normal terminal, type Ctrl+a and then d. You can now log out safely without terminating the rake task.
As a bonus, you automatically get a log file in screenlog.0.
You can come back to your rake process by typing :
screen -r

Capistrano deploy slow due to assets - .sprockets-manifest*

When deploying our API (which doesn't use assets at all), it hangs for about 5 minutes on this line:
DEBUG [985661f8] cannot access /var/www/api.staging/releases/20160208111413/public/assets/.sprockets-manifest*
DEBUG [985661f8] : No such file or directory
We have already disabled assets in config/application.rb:
config.assets.enabled = false
What else needs to be done? We're using these versions:
capistrano (3.4.0)
capistrano-bundler (1.1.4)
capistrano-rails (1.1.3)
capistrano-rails-collection (0.0.3)
Capistrano log:
INFO [42c93c96] Running /usr/local/rvm/bin/rvm 2.1.0#appyapi.staging do bundle exec rake assets:precompile as deploy#139.162.4.97
DEBUG [42c93c96] Command: cd /var/www/appyapi.staging/releases/20160223041856 && ( RAILS_ENV=staging /usr/local/rvm/bin/rvm 2.1.0#appyapi.staging do bundle exec rake assets:precompile )
INFO [42c93c96] Finished in 279.004 seconds with exit status 0 (successful).
DEBUG [f2410fde] Running /usr/bin/env if test ! -d /var/www/appyapi.staging/releases/20160223041856; then echo "Directory does not exist '/var/www/appyapi.staging/releases/20160223041856'" 1>&2; false; fi as deploy#139.162.4.97
DEBUG [f2410fde] Command: if test ! -d /var/www/appyapi.staging/releases/20160223041856; then echo "Directory does not exist '/var/www/appyapi.staging/releases/20160223041856'" 1>&2; false; fi
DEBUG [f2410fde] Finished in 0.081 seconds with exit status 0 (successful).
INFO [fd9b639a] Running /usr/bin/env mkdir -p /var/www/appyapi.staging/releases/20160223041856/assets_manifest_backup as deploy#139.162.4.97
DEBUG [fd9b639a] Command: cd /var/www/appyapi.staging/releases/20160223041856 && /usr/bin/env mkdir -p /var/www/appyapi.staging/releases/20160223041856/assets_manifest_backup
INFO [fd9b639a] Finished in 0.078 seconds with exit status 0 (successful).
DEBUG [462a5734] Running /usr/bin/env ls /var/www/appyapi.staging/releases/20160223041856/public/assets/.sprockets-manifest* as deploy#139.162.4.97
DEBUG [462a5734] Command: cd /var/www/appyapi.staging/releases/20160223041856 && /usr/bin/env ls /var/www/appyapi.staging/releases/20160223041856/public/assets/.sprockets-manifest*
DEBUG [462a5734] ls: cannot access /var/www/appyapi.staging/releases/20160223041856/public/assets/.sprockets-manifest*
DEBUG [462a5734] : No such file or directory
DEBUG [462a5734] Finished in 0.079 seconds with exit status 2 (failed).
OK, first it is important to know that the "No such file or directory" error is benign. Capistrano executes certain commands as tests and takes different code paths based on the results, and it is completely normal that some of those tests result in failures. Unless Capistrano raises an exception, you can safely ignore these "errors".
Second, it seems that rake assets:precompile is being run even though you are not using the asset pipeline, and therefore have no use for it. I'm surprised this step could take so long if you don't have any assets, but let's leave that for another discussion.
The quick solution is to not include the asset pipeline steps of the capistrano-rails plugin. As explained in the README, you can do this by including only the steps you need.
So:
# Put these in your Capfile
require "capistrano/bundler"
require "capistrano/rails/migrations"
# REMOVE these lines so that asset pipeline steps are excluded
# require "capistrano/rails"
# require "capistrano/rails/assets"

capistrano not running migrations in staging

I am using capistrano 3 and I run cap staging deploy. After various commands, it then runs rake db:migrate, which looks like this:
INFO [f67aeefb] Running /usr/local/rvm/bin/rvm ruby-2.1.2#core do
bundle exec rake db:migrate as deploy#10.10.4.131 DEBUG [f67aeefb]
Command: cd /var/www/mysite_staging/releases/20150617233945 && (
RAILS_ENV=staging /usr/local/rvm/bin/rvm ruby-2.1.2#core do bundle
exec rake db:migrate ) DEBUG [f67aeefb] "Env => staging"
The problem is the migration appears to have run in production, not in staging.
How can I ensure capistrano runs the migrations in staging when I specify staging during the deploy?
I'm not sure which of it did it, but by adding the following to staging.rb:
set :rails_env, 'staging'
set :database_name, 'core_staging'
And then in my apache virtual host adding:
RailsEnv staging
It seems to now recognize the staging database.

Issue with running bundle using Capistrano

I've seen this issue in a few other questions/Github issues, but they haven't been able to shed enough light to lead to the solution.
The error:
bash: bundle: command not found
SSHKit::Runner::ExecuteError: Exception while executing as my-user#my-IP-address: cd /path-to-my-app/current ; bundle exec unicorn -D -c config/unicorn.rb -E production exit status: 127
cd /path-to-my-app/current ; bundle exec unicorn -D -c config/unicorn.rb -E production stdout: Nothing written
cd /path-to-my-app/current ; bundle exec unicorn -D -c config/unicorn.rb -E production stderr: bash: bundle: command not found
I'm using the latest version of Capistrano on my rails app. Specifically, it's a Rails 4.2.0 app with the gems capistrano-rails and capistrano-rvm.
I have a pretty standard config/unicorn.rb file, which is how I start unicorn while logged into my server. I first kill the current PID with:
kill -9 PID
Then I start unicorn with:
bundle exec unicorn -D -c /path-to-my/config/unicorn.rb -E production
This works great, but obviously I need capistrano to do that, so I essentially have those tasks in my deploy.rb file, however I get that error mentioned above. Here are the two tasks I have in deploy.rb:
namespace :deploy do
namespace :unicorn do
task :restart do
on roles(:app), in: :sequence, wait: 5 do
execute "kill -s USR2 `cat /path-to-my/tmp/pids/app-name.pid`"
end
end
desc 'Start unicorn'
task :start do
on roles(:app), in: :sequence, wait: 5 do
execute "cd #{current_path} ; bundle exec unicorn -D -c config/unicorn.rb -E production"
end
end
end
end
I have a similar task to restart DelayedJob, which throws the same error. The command is execute "cd #{current_path} ; RAILS_ENV=production bin/delayed_job -n2 restart". Like I mentioned above, when logged into the server with my user (same user I use for Capistrano), all of these tasks work as expected.
Every other built-in task works great with Capistrano, like precompiling assets, migrating my database, etc. It is the custom tasks I've added that are getting the error.
Let me know if I can add anything to help solve the problem.
Look at output of Capistrano carefully. Such commands as bundle assets:precompile makes initialization of required ruby version:
cd /<app path>/20150301211440 && ( RAILS_ENV=staging /usr/local/rvm/bin/rvm 2.1.5 do bundle exec rake assets:precompile )
Seems like you don't do it. So, probably you a using system ruby by default and it doesn't have a bundler gem.
Try to specify ruby version use RVM in your commands too. I think it should fix your problem.

Resources