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 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.
I have an app on (ruby/rails) heroku. It's running 1 web and 1 worker (for example)
I want to be able to tell what "type" of dyno the app is running under.
I suspect it's a simple thing to tell, but I can't see anything that tells me how to tell.
I don't know if there's a more elegant way to do this, but you can set an environment variable in your Procfile:
web: bundle exec ... PROC_TYPE=web
worker: bundle exec ... PROC_TYPE=worker
Then in your rails code, you can check ENV['PROC_TYPE']
EDIT: more detailed Procfile example, typical for a rails app:
web: bundle exec rails server -p $PORT PROC_TYPE=web
worker: bundle exec rake jobs:work PROC_TYPE=worker
I'm having a problem getting Sidekiq up and running on my Heroku deployed Rails app. I have my app working fine in development (and on Heroku without Sidekiq).
I created a Procfile with:
worker: bundle exec sidekiq
If I run heroku ps, the only process I see is web.1.
Should I see one for
Sidekiq?
I do get an error:
Redis::CannotConnectError (Error connecting to Redis on localhost:6379) in my Heroku logs.
UPDATE: Found I probably needed heroku addons:add redistogo. Still not working. I feel I'm missing some basic configuration.
Is there something I need to do to get Redis up and running for my Heroku app?
I've been using Redis/Sidekiq for about a day, so this is new to me.
Thanks!
Greg
No you do not need any config with Heroku for Sidekiq, just add the RedisToGo plugin and you're on.
Do not forget to attribute at least 1 worker to your app in your Heroku config.
Here is my default Procfile:
web: bundle exec thin start -p $PORT
worker: bundle exec sidekiq -c 5 -v
It's worth checking if the sidekiq process is really started with this command:
heroku ps
If there's no worker, then you might need to run this command:
heroku ps:scale worker+1
It turns out that there's a bug in the web UI in that some team members were not allowed to increase the number of workers from 0 to 1, even though the UI seemed to show that!
Starting with sidekiq version 3.0 there is an additional step, run heroku config:set REDIS_PROVIDER=REDISTOGO_URL in the console.
Here is the process I used for Rails 4:
In the console:
heroku addons:create redistogo
heroku config:set REDIS_PROVIDER=REDISTOGO_URL
In my Procfile I added:
worker: bundle exec sidekiq
In my gemfile.rb I added:
gem 'redis'
I added the following file, config/initializers/redis.rb:
uri = ENV["REDISTOGO_URL"] || "redis://localhost:6379/"
REDIS = Redis.new(:url => uri)
Here is the link to the sidekiq docs.
Complementing gdurelle answer:
You do need some config with Heroku for Sidekiq:
1) Have the Sidekiq and Redis gems installed (in gemfile and bundled), in my case:
Gemfile
gem 'redis', '~> 3.1'
gem 'sidekiq', '~> 2.7', '>= 2.7.1'
2) Add a worker, if you don't have any workers created locally I suggest you create at least one, just in case, use this:
rails g sidekiq:worker Hard # will create app/workers/hard_worker.rb
should create this:
app/workers/hard_worker.rb
class HardWorker
include Sidekiq::Worker
def perform(name, count)
# do something
end
end
3) Add the Redis add-on (in my case Heroku Redis):
heroku addons:create heroku-redis:hobby-dev
4) Add your redis.rb file, in my case:
config/initializers/redis.rb
$redis = Redis.new(url: ENV["REDIS_URL"])
5) Add Procfile or config/sidekiq.yml or both, here are mine:
Procfile
worker: bundle exec sidekiq -c 1 -q default -q mailers
which you can create easier by pasting this in your terminal
echo "worker: bundle exec sidekiq -c 1 -q default -q mailers" > Procfile
config/sidekiq.yml
:concurrency: 1
:queues:
- [mailers, 7]
- [default, 5]
6) Most important part go here:
and turn on the switch for your worker, click on the pencil and then turn on the missing switch. Things should be working fine now, have a great day!
What I found out is that you have to scale process manually like so:
heroku ps:scale worker+1
Makes no sense since my Procfile said:
web: bundle exec....
worker: bundle exec sidekiq
...and one would've expectd Heroku to start the worker automatically. In the end I didn't have to scale the web process...
Also, you might have problems with this line:
worker: bundle exec sidekiq
Add flags for concurency:
worker: bundle exec sidekiq -c 5 -v
Sounds like you're almost there. It may be that you just need to set REDISTOGO_URL on the heroku config?
heroku config
should show you the redistogo value?
If you copy that to REDISTOGO_URL then sidekiq should work?
heroku config:add REDISTOGO_URL=<redistogo value>
Edit:
Sidekiq will use any of these currently: https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/redis_connection.rb#L29-L33
Edit2:
Greg is correct in that you don't need to add the config if you're using RedisToGo. But if you're using OpenRedis, or other Redis providers, then you need to add REDISTOGO_URL for Sidekiq
You can of course run sidekiq alongside your current jobs queue.
Our Procfile currently looks like this:
web: bundle exec thin start -R config.ru -e $RAILS_ENV -p $PORT
worker: bundle exec rake jobs:work
sidekiq: bundle exec sidekiq -c 5 -v
Here's what my Procfile looks like:
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
worker: bundle exec rake jobs:work
I intend to add a worker process because I wish to run some background jobs. I'm following these instructions
This is what I noticed:
No problems encountered if the worker is started separately.
When I keep the second line in the Procfile and don't not change anything else, the rails server serves a couple of requests and hangs after that
As mentioned here , I've added STDOUT.sync = true to config/environments/development.rb and verified the same in the rails console. Did not work.
Tailed log/development.log and compared it against the stuff that foreman outputted to the shell and noticed that both matched for a couple of requests and then foreman stopped printing out stuff to the shell - the next request would then hang
I updated foreman using foreman.pkg as mentioned here and verified the same with [6]
It was mentioned here that this might be caused due to a stray debug statement. I'm not using the debugger and I do not have the pry gem or the ruby-debug gem in my Gemfile.lock
I believe the symptoms are similar to this related unanswered question
Please help!
[6]:
which foreman
/usr/bin/foreman
ls -lah /usr/bin/foreman # checked the updated date
Tracked and resolved here:
https://github.com/ddollar/foreman/issues/244
TL;DR: Install the gem, don't use foreman.pkg
I'll add than if you're using Heroku, the foreman version included with the heroku toolbelt has the same issue.
Use the one you can get with gem install foreman instead.