bundler: not executable: script/delayed_job - ruby-on-rails

I'm trying to run the following command on my remote server (either via capistrano or ssh):
bundle exec RAILS_ENV=production script/delayed_job start
But I'm getting this error message: bundler: not executable: script/delayed_job
Never saw this before, and google had nothing for me. Any idea what might be the problem?

Maybe it does not have permissions to run? Try running this command
chmod +x script/delayed_job
and then executing the file again.

I am not sure if if it is a fundamental misunderstanding of the capistrano rbenv gem or some issue with the gem itself, but I had similar issue with delayed_job, where the bin/delayed_job file just would not get the executable permission when copied to the server by capistrano. So I wrote a task which I had run before invoking the delayed_job:restart task.
Note - Adding this answer because earlier one is from 2014, and also I wanted to show how to add the task, so the permission change can happen during deployment itself.
Created a task in lib/capistrano/tasks folder (in namespace delayed_job):
namespace :delayed_job do
desc 'Ensure that bin/delayed_job has the permission to be executable. Ideally, this should not have been needed.'
task :ensure_delayed_job_executable do
on roles(delayed_job_roles) do
within release_path do
execute :chmod, :'u+x', :'bin/delayed_job'
end
end
end
end
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'delayed_job:ensure_delayed_job_executable'
invoke 'delayed_job:restart'
end
end

Related

Cron job not being updated by whenever gem

Having a series of rake tasks that should be translated by the whenever gem into the cron file, I was wondering why the takes shows were pointing to an old release.
It cannot be asserted that whenever is active somehow, even though it is listed in the gem file (and associated lock file) and deployment refers to whenever in the deployment as follows:
tar: DEBUG [1f7d4e56] bin/whenever: time stamp 2016-01-08 15:01:20 is 88.787104175 s in the future
update Checking bundle exec whenever -v returns the proper version. Need bundle exec there...
Capfile includes require "whenever/capistrano" after calls to bundler and rails.
require 'capistrano/bundler'
require 'capistrano/rails'
require 'whenever/capistrano'
Note: this is being tested in development mode.
Functional answer. The instructions are misleading If you don't need different jobs running on different servers in your capistrano deployment, then you can safely stop reading now and everything should just work the same way it always has. Keep on reading.
The nugget is nested after this statement. Roles default to [:db]. Thus two sources of error are possible:
different job_roles on different machines are not specified in schedule.rb
Check your environment file. If "db" is not listed, whenever will not fire.
I had the same issues with using Capistrano whenever plugin, I solved it by making custom deploy shell scripts, cap production deploy being one command of many, and then inclding cap production cron:regen; inside this script I called deploy.sh, with the command inside the deploy.rb being:
namespace :cron do
desc "restart cron"
task :regen do
on roles(:app) do |host|
rails_env = fetch(:stage)
execute_interactively "crontab -r;bundle exec whenever --update-crontab;crontab -l;"
end
end
end
def execute_interactively(command)
port = fetch(:port) || 22
exec "ssh root##{fetch(:ip)} -t 'cd SERVER_PATH_OF_YOUR_APP && #{command}'"
end
I use these functions for all types of different commands, since Capistrano still gives me problems with a lot of native plugins it uses.
If you're not happy with the whenever/capistrano, you can create yourself a simple Capistrano task to update the cron jobs:
namespace :deploy do
desc "Update crontab with whenever"
task :update_cron do
on roles(:app) do
within current_path do
execute :bundle, :exec, "whenever --update-crontab #{fetch(:application)}"
end
end
end
after :finishing, 'deploy:update_cron'
end
The task will be called when the code deployment is finished.

Upstart script using foreman export is using wrong ruby version

I have just recently deployed my application to production server, but it looks that that every process I have added to my .procfile (foreman) is not started at all. Details:
I am using Rails 4.0.12, foreman 0.78.0, sidekiq 3.4.2 and clockwork 1.2.0. I am using Capistrano and I have defined a task to export procfile as an upstart service on Ubuntu 14.02. But when I start the service, no background jobs are processed. When I take look at the log files of that upstart service, I just see the following:
Your ruby version is 1.9.3, but your Gemfile specified 2.1.2
Application is running, I can see on sidekiq dashboard that nothing is processed. Based on the error message, it looks like that I am executing my procfile somehow wrong. I have tried multiple execution scenarios, but nothing seems to work. My .procfile currently looks like this:
worker: rbenv sudo bundle exec sidekiq -C config/sidekiq.yml -e production
clock: rbenv sudo bundle exec clockwork config/clock.rb
One part of exported upstart script looks like this for example:
start on starting aaa-clock
stop on stopping aaa-clock
respawn
env PORT=5100
setuid da_admin
chdir /var/www/aaa/releases/20150728172635
exec rbenv sudo bundle exec clockwork config/clock.rb
If i try the last two commands alone in bash, it works, but when i start the service "sudo service aaa start" or "rbenv sudo service aaa start", it doesn't work.
Part of deploy.rb where I am exporting my upstart service:
namespace :foreman do
desc "Export the Procfile to Ubuntu's upstart scripts"
task :export do
on roles(:app) do
within release_path do
execute :rbenv, "sudo bundle exec foreman export upstart /etc/init -a #{fetch(:application)} -u #{fetch(:user)} -l #{current_path}/log -f #{release_path}/Procfile"
end
end
end
desc "Start the application services"
task :start do
on roles(:app) do
execute :rbenv, "sudo service #{fetch(:application)} start"
end
end
desc "Stop the application services"
task :stop do
on roles(:app) do
execute :rbenv, "sudo service #{fetch(:application)} stop"
end
end
desc "Restart the application services"
task :restart do
on roles(:app) do
execute :rbenv, "sudo service #{fetch(:application)} restart"
end
end
end
Does anybody has any idea what could be wrong? I suspect, that this will be some mistake in environment configuration. Thank you in advance for your time.
EDIT:
The problem was at the end in environment of the upstart script, similar problems which pointed me in the right direction were:
foreman issue
foreman another issue
I had to create .env file with configuration of various environment variables. Now it atleast starts (other bugs arised, but they are not related to this issue).
Example of the .env file in the root of project directory:
PATH=/home/user/.rbenv/versions/2.1.2/bin:/usr/bin
RAILS_ENV=production
HOME=/home/user

Rails - Run Rake tasks with Capistrano

Im scratching my head here wondering if I'm barking up the wrong tree. I have a server which I've deployed a Rails app onto using Capistrano. Recently I added a new data type to one of the models, and now I need to run a Rake task to update the existing records.
After a lot of Googling I'm starting to wonder if people use Rake tasks with Capistrano. Some forum posts from 2013 or so mention that Capistrano supports the .rake extension. Whereas other posts I've found indicate that Capistrano has its own task automation system, and is incompatible with rake.
I found Cape, but I'm unsure if this is what I'm looking for as it seems to convert Rake tasks into cap recipes. Its possible I'm mistaken on this point, I really don't have any experience working with Capistrano or even working in the full stack spectrum.
What I'm wondering is this: How do I run a simple Rake task on my remote server?
Some quick points for clarity, I've installed the app on the latest Ubuntu LTS, 14.10 if memory serves. I followed the tutorial found here. I have full sudo access and I can ssh into the server.
thanks in advance for helping a noob
If you need to update models, you can of course write a Rails migration - this will ensure that it's run if it hasn't been run yet.
The easiest way to execute a rake task on the server would be just via ssh if it's a one-time task. See the last paragraph in the tutorial you mentioned:
cd /opt/www/testapp/current ; bin/rake RAILS_ENV=production db:seed
To answer your original question about rake: you can execute rake tasks via capistrano similar to how you would execute it locally, only within the capistrano script. Here's an example:
deploy.rb:
namespace :rake do
desc "My task"
task :my_task do
on roles(:app) do
within "#{current_path}" do
with rails_env: :production do
execute :rake, "my_task"
# !!!see NOTE at end of answer!!!
end
end
end
end
end
You can view all your cap tasks via cap -T locally. The capistrano task I wrote above should show up as cap tasks:my_rake_task.
If you want to be ably to run any available rake task without configuring, do the following:
namespace :rake do
desc "Invoke rake task"
task :invoke do
on roles(:app) do
within "#{current_path}" do
with rails_env: :production do
execute :rake, ENV['task']
# !!!see NOTE at end of answer!!!
end
end
end
end
end
Then you can write:
cap production deploy:invoke task=my:rake:task
NOTE: you might want to replace the execution line with
run "bin/rake RAILS_ENV=#{rails_env} #{ENV['task']}"
to use the same syntax as the tutorial (without the binstubs you might need to configure capistrano/bundler and capistrano/rbenv first ...)
Check out capistrano-rake
Once installed, run any rake task on your production/staging servers without messy capistrano recipes by simply doing this:
$ cap production invoke:rake TASK=your:rake:task
Full Disclosure: I wrote it

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!

Delayed job wont start using Capistrano

I cannot start delayed job process using a capistrano recipe. Here's the error I am getting.
/usr/local/lib/ruby/gems/1.9.1/gems/delayed_job-2.1.1/lib/delayed/command.rb:62:in `mkdir': File exists - /my_app/server/releases/20101120001612/tmp/pids (Errno::EEXIST)
Here's the capistrano code (NOTE-: I have tried both start/restart commands)
after "deploy:restart", "delayed_job:start"
task :start, :roles => :app do
run "cd #{current_path}; RAILS_ENV=#{rails_env} script/delayed_job -n 2 start"
end
More detail errors from deployment logs -
executing command
[err :: my_server] /usr/local/lib/ruby/gems/1.9.1/gems/delayed_job-2.1.1/lib/delayed/command.rb:62:in `mkdir': File exists - /my_app/server/releases/20101120001612/tmp/pids (Errno::EEXIST)
[err :: my_server] from /usr/local/lib/ruby/gems/1.9.1/gems/delayed_job-2.1.1/lib/delayed/command.rb:62:in `daemonize'
[err :: my_server] from script/delayed_job:5:in `<main>'
command finished
failed: "sh -c 'cd /my_app/server/current; RAILS_ENV=production script/delayed_job -n 3 restart'" on myserevr
This is a Rails 3 app (v3.0.3)
Seeing the same problem.
It turns out I was missing the ~/apps/application_name/shared/pids directory.
Finally creating it made this problem go away.
No need to set up custom dj_pids directory.
I also got this error and found a couple of issues:
Ensure you have a shared/pids folder.
Ensure you have the correct hooks setup
Your deploy.rb script should contain:
require "delayed/recipes"
after "deploy:stop", "delayed_job:stop"
after "deploy:start", "delayed_job:start"
after "deploy:restart", "delayed_job:restart"
I'd copied the hooks from an old post and they appear to be incorrect now. These are from the actual delayed_job recipe file comments.
I believe cap deploy:setup should create the pids folder but I set things up a different way and it was not created. app/current/tmp/pids links to app/shared/pids and this was causing the false directory exists error.
This is how I fixed the issue, I passed an explicit pids dir parameter using "--pid-dir". Not sure if this is perfect, but it worked.
task :restart, :roles => :app do
run "cd #{current_path}; RAILS_ENV=#{rails_env} script/delayed_job -n #{dj_proc_count} --pid-dir=#{app_root}/shared/dj_pids restart"
end
Add the creation of this directory before
after "deploy:restart", "delayed_job:start"
task :start, :roles => :app do
run "mkdir #{current_path}/tmp/pids"
run "cd #{current_path}; RAILS_ENV=#{rails_env} script/delayed_job -n 2 start"
end
I had the same issue. Turned out that there was an existing
application_name/shared/pids/delayed_job.main.pid
file, which had incorrect owner permissions, which was causing the deployment to fail. Fixing this file's permissions solved the issue for me.
Since the creation of the directories is cheap and fast, use the following callback:
before 'deploy', 'deploy:setup'
This will ensure that structure is always there before each deploy.

Resources