I have a rake task which generates some static pages. I need the task to run either during deployment so the pages end up in the slug (preferable), or after each dyno cycle. Is there a way to do that? It is a Rails app.
You have a number of options here.
Customize the buildpack so that your static files end up in the release, that is the only point that you can control the contents of the slug and therefore have the files present when a dyno starts.
Another option, if you really need to do this - and I would advise against this as if it takes too long then the boot will be timed out, but you can do
web: rake mytask && rails s -p $PORT
in your Procfile. This will ensure that the dyno itself has the static files available on it when it starts.
Related
My Rails app on Heroku has a number of processes defined in the Procfile
Is there a way for an app to know what process name started it?
e.g. for Procfile:
web: rails s
job: run jobs
Is there an ENV variable (or similar) available within the running process to know if its web or job?
Apparently Heroku sets up DYNO variable, as per https://devcenter.heroku.com/articles/dynos#local-environment-variables
I'd like to configure a Heroku app to run a scheduled task once per day. My source tree looks like this:
bin/myScript
Procfile
package.json
When I deploy the app, I see the following error:
2017-01-11T04:31:36.660973+00:00 app[web.1]: npm ERR! missing script: start
I believe this is because Heroku tries to spin up a web dyno. I don't have a web dyno, nor do I want one. So I created a Procfile with this line:
heroku ps:scale web=0
To prevent heroku from spinning up a web dyno. That didn't work. What else can I do to prevent my app from crashing upon deployment? Does it matter if the scheduled task is going to be run in a separate one-off Dyno anyway?
You should not have the line "heroku ps:scale web=0" in your Procfile.
Doing so tells heroku to create a process type called "heroku" that attempts to run the following command on any dyno instances instantiated for it: "ps:scale web=0". That would probably generate errors, and at any rate, is not what you intended.
Instead You should run "heroku ps:scale web=0" as a Heroku toolbelt CLI command (or do the equivalent from the Resources tab of the GUI, as you already did).
I think I found a fix: in the "Resources" tab of the GUI for the web, there is a list of dynos with on/off sliders next to them. I switched the web dyno slider to off, and now when I deploy there is no crash. Still, it's unclear to me why the Procfile line was insufficient.
Use case is to bust the cache.
What is a good way to run given code (or rake task) whenever a Ruby Heroku app is restarted (or deployed)?
There's no way to do this via the Heroku API far as I know. The Heroku Platform API doesn't support this.
What you can do (if you're fast, however!) is listen for a SIGTERM message in your code (that's what Heroku sends to your application process when it attempts to restart it) -- you can then fire off your script quickly.
Here's more information on SIGTERM on Heroku: https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm
If you're using some sort of CI, you can probably configure it there. Heres how to do it with CircleCI:
deployment:
production:
branch: production
commands:
- git push git#heroku.com:foo-bar-123.git $CIRCLE_SHA1:master
- heroku run rake <your task> --app <your app name>
If you're not using a CI you can still whip together a script that first does the git push to Heroku and then executes your cache busting task through heroku run (the app's bin/ folder would be an obvious place to put it).
Note: you can also use heroku run:detached, which will send output to your logs instead of stdout.
You can use "release" feature that allows you to run any command before a new release is deployed. https://devcenter.heroku.com/articles/release-phase
Define the command that should be run in your Procfile.
release: rake db:migrate
From documentation:
The release command is run immediately after a release is created, but before the release is deployed to the app’s dyno formation. That means it will be run after an event that creates a new release.
I have some miniapp that use delayed_job. On my localhost everything works fine, but when I deploy my app to Heroku and click on the link that should be executed by delayed_job, so nothing happen, the "task" is just saved into the table delayed_job.
In this article on heroku blog is written, that the task from delayed_job table is executed, when is run this command rake jobs:work.
But how can I run this command? Where should be the command placed? In the code, or from terminal console?
If you are running the Cedar stack, run the following from the terminal console:
heroku run rake jobs:work
If you are running the older stacks (Bamboo, Aspen, etc.):
heroku rake jobs:work
see: https://devcenter.heroku.com/articles/rake
According to the delayed_job documentation, you can also start a worker programmatically:
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment'
Delayed::Worker.new.start
You should use a Procfile to scpecify the commands for your dynos.
For example you would have something like this in your Procfile:
appDir/Procfile
web: bundle exec rails server -p $PORT
worker: bundle exec rake jobs:work
To use this on your development machine, you should use Foreman, it's all explained at the docs.
https://devcenter.heroku.com/articles/procfile
In our case we're only running a delayed job once a month, so didn't want to have a worker dyno running constantly.
To solve this we queue up the job (with .delayed) and then use the Heroku platform API to spawn rake jobs:workoff in a one-off worker. The API call returns relatively quickly.
PlatformAPI.connect_oauth(ENV["YOUR_HEROKU_KEY"]).dyno.create(ENV["YOUR_HEROKU_APP_NAME"],{command: 'rake jobs:workoff'})
I'm adding Resque-Scheduler in my app on Heroku
So... I need ONE alone and distinct worker acting as the scheduler and
many doing the jobs.
This is how I've done it :
I've a distinct Heroku App which does nothing but has 1 resque-scheduler worker, running 24/7, adding Resque tasks to the Redis DB of the "distant" main App.
(I do that mapping jobs:work task to resque:scheduler or resque:work)
Is this the best way to do it on the Heroku's platform ; or am I doing it totally wrong ?
Thanks !
EDIT:
minimal app for scheduling on Heroku :
http://github.com/clmntlxndr/heroku-scheduler
UPDATE: With the new CEDAR stack on Heroku and Procfiles, it's possible to start a distinct task for each worker.
web: bundle exec rails server -p $PORT
scheduler: bundle exec rake resque:scheduler
worker: bundle exec rake jobs:work
http://devcenter.heroku.com/articles/procfile
I think I misread your question the first time. I missed the part where scheduler requires a separate rake task.
Yes, I think the only way to do it is to have two separate heroku apps, because heroku workers will only run rake jobs:work and presumably you can only map this onto one of the resque rake tasks.
You could try this:
desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => ["resque:work", "resque:scheduler"]
But I have sincere doubts about that actually working properly with how Heroku monitors worker processes and stuff. Also, double check the rake syntax there; it's just from memory. I know it's possible to specify multiple dependencies though.