Run rake task on Heroku with arguments and the Heroku app specified - ruby

I have a rake task that I used to run with arguments like this:
heroku rake query:process -a myherokuapp
Now that rake task accepts arguments. If I were running it locally, I can call them like this:
rake query:process -- -d true -c false
When I try to run this process on Heroku, it doesn't like the combination of the arguments and the app.
# These don't work
heroku rake query:process -- -d true -c false -a myherokuapp
heroku -a myherokuapp rake query:process -- -d true -c false
Is it possible to run this rake task with arguments on Heroku?

This should work:
heroku -a myherokuapp run rake:process -- -d true -c false

Related

Bash script not navigating to folder, only accepting input when "exit" is typed manually

I have the following bash script I am trying to use so I can speed up updates to my code. For some reason it gets stuck at cd /var/www/myapp/code and only prompts input when I type exit to return to the root user.
#!/bin/bash
# Pulls from remote repo and implements changes
su - rails
cd /var/www/myapp/code
git pull
expect "sername for 'https://bitbucket.org':"
send "myusername"
interact
expect "assword for 'https://username#bitbucket.org':"
send "mypassword"
interact
exit
cd /var/www/myapp/code
RAILS_ENV=production bundle exec rake assets:clobber
RAILS_ENV=production bundle exec rake assets:precompile
nginx -t && sudo nginx -s reload
I tried manually entering cd /var/www/myapp/code but it's still not executing until I type exit.
Well, it's a bit of re-factoring, but a solution is to wrap everything in a single su - (user) -c "bla" call, which will automatically exit the subshell as (user) once the commands are all done.
Syntax:
su - (user) -c "command"
Here's how I'd do it:
Note that we have to break commands up with ';', and escape double-quotes with a '\'.
#!/bin/bash
# Pulls from remote repo and implements changes
su - rails -c "cd /var/www/myapp/code;
git pull;
expect \"sername for 'https://bitbucket.org':\";
send \"myusername\";
interact;
expect \"assword for 'https://bitbucket.org':\";
send \"mypassword\";
interact" # Now that the final command's ran,
# we'll auto - exit the subshell
cd /var/www/myapp/code
RAILS_ENV=production bundle exec rake assets:clobber
RAILS_ENV=production bundle exec rake assets:precompile
nginx -t && sudo nginx -s reload

Starting sidekiq with capistrano

I want to start sidekiq with capistrano. Below is code for that
namespace :sidekiq do
task :start do
run "cd #{current_path} && bundle exec sidekiq -c 10 -e production -L log/sidekiq.log &"
p capture("ps aux | grep sidekiq | awk '{print $2}' | sed -n 1p").strip!
end
end
It executes successfully but still sidekiq is not started on server.
output:
$ cap sidekiq:start
triggering load callbacks
* 2014-06-03 15:03:01 executing `sidekiq:start'
* executing "cd /home/project/current && bundle exec sidekiq -c 10 -e production -L log/sidekiq.log &"
servers: ["x.x.x.x"]
[x.x.x.x] executing command
command finished in 1229ms
* executing "ps aux | grep sidekiq | awk '{print $2}' | sed -n 1p"
servers: ["x.x.x.x"]
[x.x.x.x] executing command
command finished in 1229ms
"19291"
Your problem lies here:
cd /home/project/current && bundle exec sidekiq -c 10 -e production -L log/sidekiq.log &
When you add & at the end command is being executed in a separate process, but this process is still a child of a current process and is terminated when current process stops. Instead you need to run sidekiq as a deamon.
bundle exec sidekiq -c 10 -e production -L log/sidekiq.log -d
Note the extra -d option
Without making use of any gem, here is my solution working perfectly with Capistrano 3.4.0
namespace :sidekiq do
task :restart do
invoke 'sidekiq:stop'
invoke 'sidekiq:start'
end
before 'deploy:finished', 'sidekiq:restart'
task :stop do
on roles(:app) do
within current_path do
pid = p capture "ps aux | grep sidekiq | awk '{print $2}' | sed -n 1p"
execute("kill -9 #{pid}")
end
end
end
task :start do
on roles(:app) do
within current_path do
execute :bundle, "exec sidekiq -e #{fetch(:stage)} -C config/sidekiq.yml -d"
end
end
end
end
Just in case somehow trying to start/restart/stop environment with capistrano:
bundle exec cap production sidekiq:start
bundle exec cap production sidekiq:stop
bundle exec cap production sidekiq:restart
#staging
bundle exec cap staging sidekiq:start
bundle exec cap staging sidekiq:stop
bundle exec cap staging sidekiq:restart
#same with other dependencies
bundle exec cap production puma:restart
bundle exec cap staging puma:stop
Brief explanation
(in case you are hitting a repo online, like github remember to run your ssh agent to connect via ssh in the repo and pull latest version of the code/branch)
setup your own github ssh key locally
run ssh agent with the key eval $(ssh-agent) && ssh-add ~/.ssh/id_rsa
check agent with ssh -T git#github.com
After that i always use this to deploy
run capistrano targeting env bundle exec cap staging deploy
And these are really handy when you are already in prod and had issues but specially for staging, you could do individual exec depending on your Capfile (for instance most of the time i use puma as rack middleware server and sidekiq for scheculed-jobs)
Capfile
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Include 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
# https://github.com/capistrano/passenger
#
require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano/yarn"
require "capistrano/puma"
install_plugin Capistrano::Puma # Default puma tasks
require 'capistrano/sidekiq'
require 'slackistrano/capistrano'
require_relative 'lib/capistrano/slack_deployment_message'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
So in the end for executing start|stop|restart on these features enabled/installed/configured by capistrano
I could always restart puma with capistrano in production:
bundle exec cap production sidekiq:restart
bundle exec cap production puma:restart
As well as in staging:
bundle exec cap staging sidekiq:restart
bundle exec cap staging puma:restart
Hope this helps!
:D

How to set RUBY_GC_MALLOC_LIMIT with capistrano 3 on thin restart?

I use capistrano 3, rvm und bundler for my deployment.
The thin server are restarted like this:
within release_path do
execute :bundle, :exec, "thin restart -O -C config/thin/staging.yml"
end
This work fine and generate this command:
cd /var/www/foo/releases/20140320154611 && ~/.rvm/bin/rvm ruby-2.0.0-p353#foo do bundle exec thin restart -O -C config/thin/staging.yml
Now I need to restart the thin's with this setting RUBY_GC_MALLOC_LIMIT=90000000 and I dont know how to set this up in the execute command?
The script has to setup rvm for knowing bundle, and RUBY_GC_MALLOC_LIMIT for thin
Not working:
Because rvm is not set (execute :bundle # set a rvm hook)
execute "RUBY_GC_MALLOC_LIMIT=90000000", :bundle, :exec, "thin restart -O -C config/thin/staging.yml"
2.same here
execute "RUBY_GC_MALLOC_LIMIT=90000000 bundle exec thin restart -O -C config/thin/staging.yml"
I have found a solution....
execute :bundle, :exec, "'RUBY_GC_MALLOC_LIMIT=90000000 thin restart -O -C config/thin/staging.yml'"

Why does "bundle exec" eat the parameters I pass in?

When I invoke commands using bundle exec it takes the parameters I pass in. An example for this would be:
bundle exec my_command run --verbose
In this case --verbose is used as a bundler argument where as it should be used for my_command. I know the following way would work:
bundle exec 'my_command run --verbose'
Is it possible to avoid the quotes? The command I use has already a lot of quotes. I expected something like this would work but it didn't:
bundle exec -- my_command run --verbose
I don't see much documentation about this for bundler. Any ideas would be greatly appreciated.
This looks like what is a common problem when passing one command to another in the shell, and it looks like you're close to what I'd use. Instead of using:
bundle exec my_command run --verbose
Or:
bundle exec -- my_command run --verbose
Try:
bundle exec my_command -- run --verbose
Using bundle exec -- breaks the command-chain for bundle exec. exec is a sub-command for bundle and my_command is a parameter for exec. The parameters for my_command, well, neither bundle or exec needs to know about them so the -- goes where you want to break that chain of parameters to bundle.
Inspecting from source of bundler, it is default behavior to pass all the parameters after bundle exec to Kernel.exec, so the --verbose parameters will be passed to your command, not bundle.
bundle exec my_command run --verbose
will run the following under the context of bundle
Kernel.exec('my_command', 'run', '--verbose')
and
bundle exec -- my_command run --verbose
results in an error because no command/script is named --.
Check the test case here:
#!/usr/bin/env ruby
# coding: utf-8
# file: test.rb
p ARGV
test:
$ bundle exec ruby test.rb --verbose --arg1
["--verbose", "--arg1"]

Use Foreman to Start Rack App Located in Different Directory

I have a Procfile setup that is running a number of processes successfully:
# /Procfile
redis: bundle exec redis-server
sidekiq: bundle exec sidekiq -v -C ./config.yml
forward: forward 4567 mock-api
I need to add one more process - a Sinatra app that lives in a different directory on my machine. If I cd to the directory, I can start it from the Terminal with:
$ rackup -p 4567
And I can start it from a different directory using the Terminal with:
$ sh -c 'cd /Path/to/project/ && exec rackup -p 4567'
But how should I do this using foreman. I have tried adding the following, but it fails silently:
mock-api: sh -c 'cd /Path/to/project/ && exec rackup -p 4567'
Is this even possible? And if so, how?
Of all the stupid things ...
It was failing because of the hyphen in the process name.

Resources