I have a repo for multiple deployment with using capistrano-multiconfig gem. The problem is that for some applications I want to require sikideq tasks. Something like this:
if fetch(:sidekiq_enabled?)
require 'capistrano/sidekiq'
require 'capistrano/sidekiq/monit'
end
I guess that Capfile is loaded before the capistrano configs. How to deal with this?
I was in the same situation, I wanted to require some gems per project and since my command line pattern is always the same to execute capistrano tasks, this is how I deal with it.
My pattern is like this:
$ bundle exec cap project:stage namespace:task
The solution was for me to get the first argument (here project) to know what kind of project it is and require the good recipe for the project.
So in Capfile, I write something like this
[...]
# Get project from the command line if any
current_project = ARGV[0].split(':')[0]
magento_projects = ["project_1"]
symfony_projects = ["project_2"]
# Include required tasks per project
if magento_projects.include?(current_project)
require 'capistrano/magento'
end
if symfony_projects.include?(current_project)
require 'capistrano/symfony'
end
[...]
Now when I type :
$ bundle exec cap project_1:staging deploy
Or :
$ bundle exec cap project_2:production deploy:check
It'll require different gems. Done :)
Related
I have some rake tasks that I only perform locally. However since I refer to the some gem classes in rake tasks, this seems to require that the gem be installed and loaded on the production server. Among other things this increases deploy time and memory usage on the server.
This may or may not have to do with my setting:
config.autoload_paths += Dir["#{config.root}/lib/**/"]
I have a number of lib files and subdirectories.
I guess my options are to
move all my lib files somewhere else and add that path to autoload_paths
try to exclude the tasks dir from autoload_paths
do something fancy in the rake tasks themselves (if possible) to avoid the need to have the gems present.
configure rake tasks to live somewhere else (seems like a bad idea)
This seems like a pretty common issue and probably has a common way to solve it or avoid it. What am I missing?
Maybe not the most exciting answer but I just moved the require 'dev_gem' inside the rake task block for that task.
namespace :elasticbeanstalk do
desc 'Creates a new web & worker environment pair for testing'
task :create do
require 'aws-sdk-elasticbeanstalk'
# Do stuff with beanstalk that we wouldn't from a production env
end
end
This way the library only gets loaded when the rake task is invoked rather than when the rake task is defined.
doing something like this may work
require "prod_gem_name"
unless Rails.env.production?
require 'dev_gem_name'
desc "Task that run something with a dev gem"
# code that uses the gem on dev group
end
or another solution maybe will be to add those .rake files to the gitignore. maybe it wouldn't work on all cases but it's another option.
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.
I'm folowing this link to put ruby on rails start automatically.
But I cant understand its ruby code
#!/usr/bin/env ruby
require File.expand_path("../../config/environment", __FILE__) #1.what is this path?
STDOUT.sync = true
Stalker::job 'user.fetch_details' do |args| #2.what is this user?
begin
user = User.find(args['id']) #3.what is this id?
user.fetch_user_details!
rescue ActiveRecord::RecordNotFound # too fast
Rails.logger.warn "Unable to find user ##{args['id']} - suspect too fast, requeuing"
Stalker.enqueue('user.fetch_details', :id => args['id'])
end
end
jobs = ARGV.shift.split(',') rescue nil
Stalker.work jobs
and conf file code in /etc/init/
description "TweetedLinks Ruby Worker"
# automatically start
start on filesystem
# working directory
chdir /var/www/TweetedLinks/current #4.should I change this to my own dir?ie home/usr/Trail/test-app
# command to run, with Bundler support!
env RAILS_ENV=production
exec bundle exec ruby script/worker.rb >> log/worker.log #5.do i need to create this worker.log? and this script folder can be put anywhere?
respawn
I have my rails app under home/usr/Trail/test-app
I have create a script folder under home/usr/script
I have my rvm generated under home/usr/.rvm/wrapper/test-app
How to modify this code according to my situation.
and the 5 question in code comments I also very confuse.
Thanks in advance!have been stuck for month!
The easiest way would be to use foreman gem that can export Procfile to upstart, see http://ddollar.github.io/foreman/#UPSTART-EXPORT
My environment is Macbook OSX 10.7 Lion with Ruby 2.0 and Rails 4.
I am new to RoR. I built a website with one column database using a scaffold.
It's just a little website about weather.
I want to input degrees to database every hour.
And I found the gem clockwork, but I have no idea how to use it with my project.
I wrote clock.rb and put it in my project file and ran rails s but nothing happened.
Here is myproject/clock.rb
myproject/clock.rb
require 'clockwork'
module Clockwork
handler do |job|
puts "Running #{job}"
every(1 hours, ''){
Mydata.create(:degree => input_data)
}
end
What should I do with it or where should I put the file?
They say that I need to use $ clockwork clock.rb, but when I run rails s, there's no way to use that...
Thanks a lot.
As stated in the official docs you need a couple of things.
setup the clock file, I've set it in app/clock.rb
require 'clockwork'
module Clockwork
handler do |job|
case job
when 'weather.input_degree'
Mydata.create degree: input_data
# when 'some_other_task'
# ...
else
puts "Couldn't find your job!"
end
end
every(1.hour, 'weather.input_degree') # the string indicates an arbitrary job name
# every(20.seconds, 'weather.some_other_task')
end
The starting process. The key is to use something like Foreman
$ gem install foreman
Create a file named Procfile in root of your app:
web: bundle exec rails -s
clock: bundle exec clockwork app/clock.rb
# any_other_service_you_want: bash script here
start your server
$ foreman start
Add to Gemfile
gem 'clockwork'
after adding upper listed gem in gemfile, use bundle install to add this gem into project.
Example
Create a file clock.rb under /lib directory
clock.rb
require File.expand_path('../../config/boot', __FILE__)
require File.expand_path('../../config/environment', __FILE__)
require 'clockwork'
include Clockwork
module Clockwork
## Here Student is a domain class, having a method insertRecord to
## insert a record in DB
every(20.seconds, 'job Inserting Record in DB') { Student.insertRecord }
end
Command to Run the clockword
bundle exec clockwork lib/clock.rb
This code needs stay outside of handler block:
every(1.hour, ''){ Mydata.create(:degree => input_data) }
You can execute the clock like that:
bundle exec clockwork clock.rb
You can make use of Cron. Write a rake task and call the rake task from the Cron for repeating processes.
Example (Add this to cron to run the task every hour):
0 * * * * cd /home/projectdir;rake do:task
I am having a problem running my tests from the terminal and from rake, e.g. rake test:integration
At the moment, I have the requires for test_helper.rb specified like this:
require File.dirname(__FILE__) + '/../test_helper'
This works fine when running them from the terminal but obviously when it is ran from rake, the directory is different and the process cannot find the test_helper file.
I think I want to add to this to my $load_path but I am not sure how to add it when running only in the test environment.
Can anyone help me out?
You can revert to just require 'test_helper' (the default for integration tests, at least with Rails 2.3.x). This will allow tests to run from a rake task, and as long as you cd to the test directory within your rails app, you can run tests via the terminal with ruby integration/your_test.rb.