I have a foreman app with a Procfile like this
web: bundle exec rails s
custom_process: bundle exec rake custom:process
faking_custom_process: bundle exec rake custom:faking_process
And I want to run custom_process or faking custom_process depends on my needs:
foreman start # run web & custom_process
FAKING_PROCESS # run web & faking_custom_process
Yes, I know about ability of running like that foreman start -c faking_custom_process=0, but this is more difficult than I expect, right?
There's no option in foreman to just skip a process. I think you'd need to extend your start invocation to do something different too if you want to run the other processes. Otherwise you're just telling it to run zero copies of faking_custom_process and nothing else:
foreman start -m web=1,custom_process=1,faking_custom_process=0
or for the faking version:
foreman start -m web=1,custom_process=0,faking_custom_process=1
You could of course script that so you've got two scripts running those different versions.
An alternative would be to switch faking on or off using a variable in the environment (I'm not convinced it's any easier but it's an alternative):
web: bundle exec rails d
custom_process: PROCESS=$FAKING"process" && bundle exec rake custom:$PROCESS
A normal foreman start will just run bundle exec rake custom:process.
For the faking equivalent you can do:
export FAKING="faking_"
which will mean that from then on foreman start it will call bundle exec rake custom:faking_process instead.
You can return to the normal process by clearing the FAKING variable with:
export FAKING=
You could of course encapsulate that into a shell script too.
You can use .profile to store default options for foreman start:
concurrency: web=1,custom_process=1,faking_custom_process=0
or using shortcut:
concurrency: all=1,faking_custom_process=0
And then you override this default option to switch to fake process:
foreman start -c all=1,custom_process=0
See: http://ddollar.github.io/foreman/#DEFAULT-OPTIONS
Related
Suppose there's a task
rake startupscript
that should run whenever the app boots, how can we automate that on heroku?
I know there's a heroku scheduler but that will run the task every 10 minutes instead of just once at boot. I also know of the Procfile and believe this can be a solution, although I do not yet know how to implement (and probably more importantly, I don't want to risk breaking anything else that can be configured via a Procfile, e.g. webserver etc). A lot of the Procfile docs focus on using it to alter web servers rather than app level rake tasks.
How can a rake task be made to run at boot?
You can add something like this to Procfile before you start your application services
# Run pre-release-tasks here
release: bundle exec rails db:migrate
# Then run your application
web: bundle exec puma -t 5:5 -p ${PORT:-3000} -e ${RACK_ENV:-development}
Anything tagged as release will run before the startup script runs
https://devcenter.heroku.com/articles/release-phase
I use Delayed Job as a queuing backend for Active Job on my Rails 5 app but I have no idea how to start the worker on Ubuntu 14.04 after startup. Should I wrap rails jobs:work into a Bash script? How would I have it start automatically? Or is it preferable to use bin/delayed_job?
How do I start delayed job on boot?
It does not really matter what OS you're on (as long it is not Windows :D).
To start the processing the command is:
bundle exec rake jobs:work
to restart the delayed_job the command is:
RAILS_ENV=production script/delayed_job restart
Check out gems README for more info.
EDIT
(according to the comment)
You can create some bash script in user's home start_delayed_jon.sh.
Something along the lines:
#!/bin/bash
cd /path/to/your/project/directory/
RAILS_ENV=development bundle exec rake jobs:work
and run it in /etc/rc.local:
su -s /bin/bash - deploy /path/to/your/project/directory/start_delayed_jon.sh
Using the Whenever Gem, you can setup a cronjob that runs it on reboot. In your schedule.rb file:
every :reboot do
rake 'start_delayed_jobs'
end
Then in your rake file:
desc 'Start delayed jobs'
task :start_delayed_jobs do
system("#{Rails.root}/bin/delayed_job start")
end
end
If you are using gem 'delayed_job_active_record'.
You start a delayed jobs on your local ubuntu system, simply run the below command to start
./bin/delayed_job start
and to restart
./bin/delayed_job restart
If we are in development mode, we would use the below rake task instead.
bundle exec rake jobs:work
for production:
RAILS_ENV=production script/delayed_job -n2 restart
or
RAILS_ENV=production bin/delayed_job -n2 restart
n2 is the number of delayed jobs servers you want to restart in case of start use command start instead or restart.
documentation: https://github.com/collectiveidea/delayed_job#restarting-delayed_job
I have a file with worker class (worker.rb) and I need to instantiate it in separate process from rails application after getting the command. I'm currently working on windows os.
So how to do that?
P.S. Will that code work in unix/linux env?
Check out foreman
https://github.com/ddollar/foreman
You can put a Procfile in your Rails root with instructions for starting both your rails server and your worker and then run foreman start to launch them. Here is a sample Procfile:
web: bundle exec unicorn_rails -p 8088
scheduler: bundle exec rake resque:scheduler
worker: bundle exec rake resque:work
Foreman is compatible with both Windows and Linux, so it should work regardless of your platform.
what is the "foreman way" for behaving differently in production vs
development? That is we want foreman start to start up a bunch of
stuff in dev, however in heroku production we don't need it to start
(for example) solr.
I follow the convention;
Procfile defines all processes
.foreman set specific foreman variables
Development:
.env sets environment variables for each developer
.env.example sets defaults for development
foreman start starts all processes
Production:
heroku config sets environment variables
heroku ps:scale turns on or off whichever processes are needed for production
Here's an example from a project.
Procfile:
web: bundle exec unicorn_rails -p $PORT -c ./config/unicorn.rb
worker: bundle exec rake jobs:work
search: bundle exec rake sunspot:solr:run
.env.example:
# default S3 bucket
S3_KEY=keykeykeykeykeykey
S3_SECRET=secretsecretsecret
S3_BUCKET=myapp-development
.env
# developer's private S3 bucket
S3_KEY=mememememememememe
S3_SECRET=mysecretmysecret
S3_BUCKET=myapp-development
.foreman:
# development port is 3000
port: 3000
Foreman takes arguments to use a different file (-d) and arguments to specify what to run. It also supports a .foreman file that allows those args to become default. See http://ddollar.github.com/foreman/ for more info
I've used environment-specific Procfiles before, which is pretty simple and works fine.
Basically you have Procfile.development, Procfile.production, etc. In each you can customize the procs you want to start, then run them via foreman like so:
foreman start -f Procfile.development
Another approach is to reference scripts in your Procfile, and within each script start up the appropriate process based on the environment. The creator of Foreman does this and has an example from his Anvil project your reference.
Our solution was to use a separate job type in our Procfile for dev vs. production. It is not the most DRY method, but it works...
sidekiq: bundle exec sidekiq
sidekiq-prod: bundle exec sidekiq -e production
Then we run foreman specifying the prod job on the production system:
foreman start -c sidekiq-prod=4
I need to start thin aus user - not as root. So I changed the whole environment to run the server in user-mode. Problem is, that I wanna start different thin's for different apps. But I'ld love to use bundle exec instead of gemsets - because I don't wanna update the gemsets all the time when updating the app.
So how could I change the init.d - script to start thin in bundler environment?
I tried this:
su - rubyuser -c "bundle exec /var/www/myapp/deploy/shared/bundle/ruby/1.9.1/bin/thin start -C /etc/thin/myapp.yml"
but it ends up in "Could not locate Gemfile"