Capistrano not opening rails console - ruby-on-rails

I am trying to open rails console using Capistrano but its close the connection
Following script i am using and open rails console
Code
namespace :rails do
desc "Start a rails console, for now just with the primary server"
task :c do
on roles(:app), primary: true do |role|
rails_env = fetch(:rails_env)
execute_remote_command_with_input "#{bundle_cmd_with_rbenv} rails console #{rails_env}"
end
end
def execute_remote_command_with_input(command)
port = fetch(:port) || 22
puts "opening a console on: #{host}...."
cmd = "ssh -l #{fetch(:deploy_user)} #{host} -p #{port} -t 'cd #{deploy_to}/current && #{command}'"
exec cmd
end
def bundle_cmd_with_rbenv
puts "RBENV_VERSION=#{fetch(:rbenv_ruby)} RBENV_ROOT=#{fetch(:rbenv_path)} #{File.join(fetch(:rbenv_path), '/bin/rbenv')} exec bundle exec"
if fetch(:rbenv_ruby)
"RBENV_VERSION=#{fetch(:rbenv_ruby)} RBENV_ROOT=#{fetch(:rbenv_path)} #{File.join(fetch(:rbenv_path), '/bin/rbenv')} exec bundle exec"
else
"ruby "
end
end
end
Details
I am using this script to open rails console so many time ant its work but for the couple of month rails console opening script is fail and don't know what to do with this.
Output
RBENV_VERSION=2.1.2 RBENV_ROOT=/home/deployer/.rbenv /home/deployer/.rbenv/bin/rbenv exec bundle exec
opening a console on:
Usage:
rails new APP_PATH [options]
Connection to 45.55.142.39 closed.
Any Suggestion hot it will work

Something is wrong with your binstubs.
There are two things you have to do.
1) in your deploy.rb:linked_dirs should not contain the bin directory
2) This should be in your deploy.rb:
set :bundle_binstubs, nil
and after that you may run on your local machine:
rake rails:update:bin
This will include the binstubs in your repo.
Let me know how it goes.

Related

bundler: not executable: bin/rails in rails production while using whenever gem

I'm using whenever gem for cronjobs in rails application - production.
I'm getting an error bundler: not executable: bin/rails
scheduler.rb
every 15.minute do
runner 'TestJob.perform_later()'
end
crontab
0,15,30,45 * * * * /bin/bash -l -c 'cd /home/deploy/my-app/releases/20190719103116 && bundle exec bin/rails runner -e production '\''TestJob.perform_later()'\'''
but when i run /bin/bash -l -c 'cd /home/deploy/my-app/releases/20190719103116 && bundle exec bin/rails runner -e production '\''TestJob.perform_later()'\''' in my bash replacing bin/rails with just rails this work fine.How to fix this?
Try running it via a rake task:
config/schedule.rb
every 15.minutes do
rake 'testing:run_tests'
end
lib/tasks/testing.rake
namespace :testing do
desc 'Run tests'
task run_tests: :environment do
TestJob.perform_later
end
end
Quick Answer
With the intent of still using the original runner job type, simply add this to your schedule.rb:
set :runner_command, "rails runner"
Long Answer
The documentation isn't so clear about it, but you can see the default runner job type being set as such in Whenever's /lib/whenever/setup.rb:
job_type :runner, "cd :path && :bundle_command :runner_command -e :environment ':task' :output"
In that same file you can see that this :runner_command setting is set with:
set :runner_command, case
when Whenever.bin_rails?
"bin/rails runner"
when Whenever.script_rails?
"script/rails runner"
else
"script/runner"
end
So by default your cron command will be created using bin/rails runner unless you overide it with the above answer.

rake db:dump fails when specifying an environment

I am using the gem yaml_db to generate a db dump.
The regular invocation with
rake db:dump
works as intended. However when I specify another environment like
RAILS_ENV=development-mysql rake db:dump
the command fails with:
Don't know how to build task 'db:dump'
Thanks for your ideas.
Maybe the yaml_db gem is in the development group of your Gemfile. This results in the fact that if you run RAILS_ENV=development-mysql rake db:dump Bundler loads only the general gems and not the gems from development-mysql.
You need to add yaml_db to a group named development-mysql.
Without using gem, you can dump your database with (RAILS_ENV=production) rake db:dump.
In your lib/tasks/db.rake
namespace :db do
desc "Dumps the database to backups"
task :dump => :environment do
cmd = nil
with_config do |app, host, db, user|
cmd = "db_password pg_dump -h host -d #{db} -U db_username > /path/to/file/#{db}.psql"
end
puts cmd
exec cmd
end
private
def with_config
yield Rails.application.class.parent_name.underscore,
ActiveRecord::Base.connection_config[:host],
ActiveRecord::Base.connection_config[:database],
ActiveRecord::Base.connection_config[:username]
end
end
Here is the source.

Automatically Starting ElasticSearch with Rails

I've been doing Ruby on Rails development with ElasticSearch between two machines and its starting to get a little annoying. My usual workflow is:
git pull
bundle install
rake db:migrate (or rake db:setup depending)
rails server
elasticsearch -f -D myconfig.xml
rake environment tire:import CLASS=MyObject FORCE=true
Is there anyway I can add all of these commands to some type of start up script in Rails to bring them all into one place? It would make bringing up a dev environment a lot easier on me everytime I switch machines.
The best way I've found is to use the Foreman gem to kickstart your project and associated processes.
It looks like you should do this in your deployment using Capistrano. Here is an example config/deploy.rb file:
[basic parts omitted]
after "deploy", "bundler:bundle_install"
after "bundler:bundle_install", "db:db_migrate"
after "deploy:db_migrate", "deploy:elastic_search_indexing"
namespace :bundler do
desc 'call bundle install'
task :bundle_install do
run "cd #{deploy_to}/current && bundle install"
end
end
namespace :db do
desc 'fire the db migrations'
task :db_migrate do
run "cd #{deploy_to}/current && bundle exec rake db:migrate RAILS_ENV=\"production\""
end
end
namespace :elasticsearch do
desc 'run elasticsearch indexing via tire'
task :index_classes do
run "cd #{deploy_to}/current && bundle exec rake environment tire:import CLASS=YourObject FORCE=true "
end
end
[rest omitted]
Make sure you have a config file on the target machine (Linux) in /etc/elasticsearch/elasticsearch.yml with contents like:
cluster:
name: elasticsearch_server
network:
host: 66.98.23.12
And the last point to mention is that you should create an initializer config/initializers/tire.rb:
if Rails.env == 'production'
Tire.configure do
url "http://66.98.23.12:9200"
end
end
As you can see, this is the exact same IP address, but only used for the production environment. I assume that you access elasticsearch locally (in development mode) via localhost. elasticsearch is connection per default to
http://0.0.0.0:9200
A good starting point and also in depth help is provided by awesome Ryan Bates and his Railscasts http://railscasts.com/episodes?utf8=%E2%9C%93&search=capistrano
Whats keeping you from putting it in a bash script? And put the script inside your RAILS_APP_HOME/scripts folder?
#!/bin/sh
git pull
bundle install
rake db:migrate
rails server
elasticsearch -f -D myconfig.xml
rake environment tire:import CLASS=MyObject FORCE=true

How to enter rails console on production via capistrano?

I want to enter the rails console on production server from my local machine via capistrano.
I found some gists, e.g. https://gist.github.com/813291 and when I enter console via
cap production console
I get the following result
192-168-0-100:foldername username $ cap console RAILS_ENV=production
* executing `console'
* executing "cd /var/www/myapp/current && rails console production"
servers: ["www.example.de"]
[www.example.de] executing command
[www.example.de] rvm_path=$HOME/.rvm/ $HOME/.rvm/bin/rvm-shell '1.9.3' -c 'cd /var/www/myapp/current && rails console production'
/var/www/myapp/releases/20120305102218/app/controllers/users_controller.rb:3: warning: already initialized constant VERIFY_PEER
Loading production environment (Rails 3.2.1)
Switch to inspect mode.
and thats it... Now I can enter some text, but nothing happens...
Has anybody an idea how to get that work or another solution for my problem?
I've added my own tasks for this kind of thing:
namespace :rails do
desc "Remote console"
task :console, :roles => :app do
run_interactively "bundle exec rails console #{rails_env}"
end
desc "Remote dbconsole"
task :dbconsole, :roles => :app do
run_interactively "bundle exec rails dbconsole #{rails_env}"
end
end
def run_interactively(command)
server ||= find_servers_for_task(current_task).first
exec %Q(ssh #{user}##{myproductionhost} -t '#{command}')
end
I now say cap rails:console and get a console.
For Capistrano 3 you can add these lines in your config/deploy:
namespace :rails do
desc 'Open a rails console `cap [staging] rails:console [server_index default: 0]`'
task :console do
server = roles(:app)[ARGV[2].to_i]
puts "Opening a console on: #{server.hostname}...."
cmd = "ssh #{server.user}##{server.hostname} -t 'cd #{fetch(:deploy_to)}/current && RAILS_ENV=#{fetch(:rails_env)} bundle exec rails console'"
puts cmd
exec cmd
end
end
To open the first server in the servers list:
cap [staging] rails:console
To open the second server in the servers list:
cap [staging] rails:console 1
Reference: Opening a Rails console with Capistrano 3
exec is needed to replace the current process, otherwise you will not be able to interact with the rails console.
A simple Capistrano 3 solution may be:
namespace :rails do
desc "Run the console on a remote server."
task :console do
on roles(:app) do |h|
execute_interactively "RAILS_ENV=#{fetch(:rails_env)} bundle exec rails console", h.user
end
end
def execute_interactively(command, user)
info "Connecting with #{user}##{host}"
cmd = "ssh #{user}##{host} -p 22 -t 'cd #{fetch(:deploy_to)}/current && #{command}'"
exec cmd
end
end
Then you can call it say, on staging, with: cap staging rails:console. Have fun!
For Capistrano > 3.5 and rbenv. Working in 2021
namespace :rails do
desc "Open the rails console on one of the remote servers"
task :console do |current_task|
on roles(:app) do |server|
server ||= find_servers_for_task(current_task).first
exec %Q[ssh -l #{server.user||fetch(:user)} #{server.hostname} -p #{server.port || 22} -t 'export PATH="$HOME/.rbenv/bin:$PATH"; eval "$(rbenv init -)"; cd #{release_path}; bin/rails console -e production']
end
end
end
I have fiddled with that approach as well, but then resorted to avoiding building my own interactive SSH shell client and just went with this snippet I found that simply uses good old SSH. This might not be suitable if you have some weird SSH gateway proxying going on, but for logging into a box and performing some operations, it works like a charm.
In my experience, capistrano isn't built to work very well with interactive terminals.
If you have to execute things in multiple terminals, I'd suggest iterm, which has a "send to all windows" function that works very well for me:
http://www.iterm2.com/#/section/home
I have a somewhat difficult environment, which is influx ... So bash -lc isn't really an option right now. My solution is similar to #Rocco, but it's a bit more refined.
# run a command in the `current` directory of `deploy_to`
def run_interactively(command)
# select a random server to run on
server = find_servers_for_task(current_task).sample
# cobble together a shell environment
app_env = fetch("default_environment", {}).map{|k,v| "#{k}=\"#{v}\""}.join(' ')
# Import the default environment, cd to the currently deployed app, run the command
command = %Q(ssh -tt -i #{ssh_options[:keys]} #{user}##{server} "env #{app_env} bash -c 'cd #{deploy_to}/current; #{command}'")
puts command
exec command
end
namespace :rails do
desc "rails console on a sidekiq worker"
task :console, role: :sidekiq_normal do
run_interactively "bundle exec rails console #{rails_env}"
end
end
For a Rails console in Capistrano 3 see this gist: https://gist.github.com/joost/9343156
I have just used capistrano-rails-console gem to open rails console and it is working fine.

How do I start Thinking Sphinx delayed delta rake task from deploy script?

I have Thinking Sphinx setup and working however I am having a problem getting the Delayed Job rake tasks to start during deployment.
I have the following task in deploy.rb which appears to execute, however the delayed jobs are not processed - they stack up until I run rake ts:dd from the server command line:
namespace :thinkingsphinx do
desc 'Start Delayed Job Sphinx delta indexing'
task :dd do
run "cd #{current_path} && rake ts:dd RAILS_ENV=#{rails_env} &"
end
end
How can I get the delayed jobs to start running from the deployment script?
Thanks
Simon
The link Florian provided has code by Amit Solanki that works!
Here is what I did to get this to work with Capistrano:
Install gems
ts-delayed-delta
daemon_generator
whenever
Create a file called script/delayed_delta with the contents:
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
daemon_options = {
:multiple => false,
:dir_mode => :normal,
:dir => File.join(dir, 'tmp', 'pids'),
:backtrace => true
}
puts 'delayed_delta'
Daemons.run_proc('job_runner', daemon_options) do
if ARGV.include?('--')
ARGV.slice! 0..ARGV.index('--')
else
ARGV.clear
end
Dir.chdir dir
RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.join('config', 'environment')
Delayed::Worker.new(
:min_priority => ENV['MIN_PRIORITY'],
:max_priority => ENV['MAX_PRIORITY']
).start
end
Configure Capistrano
Capistrano needs to start Sphinx and job_runner (with our script/delayed_delta).
Add something like this to the deploy.rb:
deploy.task :restart, :roles => :app do
run "export RAILS_ENV=production && cd #{deploy_to}/current && /usr/bin/rake ts:rebuild"
run "export RAILS_ENV=production && cd #{current_path} && /usr/bin/ruby script/delayed_delta start"
end
Configure whenever gem
In your config/schedule.rb add lines to update Sphinx's index and start job_runner if it isn't already running
every 30.minutes do
command "export RAILS_ENV=production && cd /path/to/rails/production && /usr/bin/rake ts:index && /usr/bin/ruby script/delayed_delta start"
end
This gets converted to a crontab that is run every 30 minutes to update sphinx
Final Notes and Lessons Learned
The script/delayed_delta uses the daemon_generator gem to start the job_runner background worker script. This is equivalent to running rake thinking_sphinx:delayed_deltas on the console, but persistent.
Make sure only one job_runner or rake thinking_sphinx:delayed_deltas process is running at one time
Let Capistrano start both Sphinx (rake ts:rebuild) and script/delayed_delta. I had problem when I started sphinx and delayed_deltas from different users or different environments
This link will be useful for anybody who need to restart the delayed_delta rake task from deploy script :
http://amitsolanki.com/2010/04/running-delayed-delta-daemon-in-background-for-thinking-sphinx/#comment-5802
I would put your delayed_job task in a separate script and run it from cron or have it started/monitored by your monitoring tool of choice (e.g., monit). Your deploy script can just kill it to make sure it restarts each time (killall job_runner). Here's the script I use:
#!/usr/bin/env ruby
## this script is for making sure and delayed_jobs get run
## it is used by thinking sphinx
require File.dirname(__FILE__) + '/../config/environment'
# you can also put the definition of this in config/environments/*.rb so it's different for test, production and development
JobRunnerPidFile = "#{RAILS_ROOT}/tmp/pids/job_runner.pid"
if File.exists?(JobRunnerPidFile)
old_pid = File.read(JobRunnerPidFile).to_i
begin
if Process.getpgid(old_pid) > 0
# still running, let's exit silently...
exit(0)
end
rescue
# looks like nothing is running, so let's carry on
end
end
File.open(JobRunnerPidFile, "w") {|f| f.write "#{$$}\n" }
Delayed::Worker.new.start

Resources