Rails 3 and Heroku: automatically "rake db:migrate" on push?
Solution 1
Here is a rake task that wraps up everything into a one-liner (and also supports rollback):
https://gist.github.com/362873
You still might wind up deploying on top of your boss's demo, but at least you don't waste time typing between the git push
and the rake db:migrate
.
Solution 2
Heroku now has the ability to handle this as part of their "release phase" feature.
You can add a process called release
to your Procfile
and that will be run during each and every deploy.
Rails >= 5 Example
release: bundle exec rails db:migrate
Rails < 5 example
release: bundle exec rake db:migrate
Solution 3
What about this simple command chaining solution:
git push heroku master && heroku run rake db:migrate
It will automatically run the migrate as soon as the first one finishes successfully. It's tipically 1-2 seconds delay or less.
Solution 4
I created a custom buildpack that gets Heroku to run rake db:migrate
for you automatically on deployment. It's just a fork of Heroku's default Ruby buildpack, but with the rake db:migrate
task added.
To use it with your app you'd do this:
heroku config:set BUILDPACK_URL=https://github.com/dtao/rake-db-migrate-buildpack
Also note that in order for it to work, you need to enable the user-env-compile Heroku Labs feature. Here's how you do that:
heroku labs:enable user-env-compile
And here's my evidence that this works:
Solution 5
Perhaps you could try separating your schema commits (migrations, etc.) commits from code commits (models, validations, etc.).
(Note the following assumes your migration changes are NOT destructive, as you've indicate covers most of your use cases.)
Your deploy process could then be:
- Push schema changes to Heroku
- migrate
- Push application code to Heroku
This is of course far form optimal, but is an effective way to avoid downtime in the situation you've described: by the time the app receive the code for the dynamic fields, the DB will already have migrated.
(Of course, the simplest solution would be to simply push and migrate while your boss is out to lunch ;-D)
Otherwise, even if schema modifications were carried out automatically you'd still run the risk of a request passing through right before the migrations have been run.
Max Williams
Updated on July 05, 2022Comments
-
Max Williams almost 2 years
I have a slight annoyance with my heroku push/deploy process, which otherwise has been a joy to discover and use.
If i add a new migration to my app, the only way i can get it up onto the heroku server is to do a push to the heroku remote. This uploads it and restarts the app. But it doesn't run the migration, so i have to do
heroku rake db:migrate --app myapp
, thenheroku restart --app myapp
. In the meantime, the app is broken because it hasn't run the migrations and the code is referring to fields/tables etc in the migration.There must be a way to change the deployment process to run the
rake db:migrate
automatically as part of the deploy process but i can't work it out.Is it something i set in a heroku cpanel? Is it an option i pass to heroku from the command line? Is it a git hook? Can anyone set me straight? thanks, max
-
Max Williams about 13 yearsThat's just not satisfactory i'm afraid: i want to be able to deploy at any time without worrying about whether my boss is demoing the site to clients or whatever (at which time the appearance of a maintenance page would mean a very angry boss). Thanks for answering though :)
-
Aditya Sanghi about 13 yearsDo you really want to be deploying while your short-fused boss is demoing? I'm not sure heroku provides this feature as yet! The best thats currently possible is no human wait in the meantime.
-
Max Williams about 13 yearsI don't want to but it inevitable happens :) In my non-heroku apps it's fine as long as the migration is non-destructive, which it almost always is (ie they are usually to add new fields or new tables, rather than delete anything). So, you have an interim period where the old code is running with the new schema, which is generally fine (as the schema only contains additions), then after the migration finishes a rolling restart of the mongrels/unicorns happpen, which has very little if any noticeable downtime/slowdown.
-
Max Williams almost 13 yearsi ended up going with your solution after Paul (below) posted an actual rake task up. Guess i was just too lazy to write my own. Thanks :)
-
GMA over 10 yearsYES. 10 seconds of work to set up and it's exactly what I was looking for. Much better than the other answers here, at least for my purposes. Thanks.
-
Dorian about 10 yearsMy recommendation would be to fork the project and use the fork as the deploy process. Because here you trust a Github repo to deploy your production code.
-
Nathan about 10 yearsI preferred an object-oriented version of the gist mentioned: gist.github.com/jfeaver/9820478
-
GMA about 10 yearsGood point. However, this repo doesn't work anymore anyway because
user-env-compile
, which it depends on, has been removed. :( -
Matt about 10 yearsShould the migration fail, this leaves you in a bit of a mess though.
-
link0ff almost 10 yearsIf the migration fails, roll back the last release. Otherwise, restart the app to use new schema changes.
-
reconbot over 9 yearsThis is great, it looks .. almost exactly like the one I use. =)
-
Gon Zifroni about 9 yearsDon't do this, on Heroku your DB connection might not be ready at that specific point in the deploy process.
-
slothbear about 9 yearsheroku_san hasn't been updated in a while, but I'm using it on Rails 4.2 projects without problems.
-
cwd over 8 yearsI think this gist may be a bit outdated now - the code seems like it is from heroku's earlier days when more manual intervention was required after a push
-
eloyesp about 8 yearsYou can force push to heroku so you can skip all those merges and just force push master after running the migration.
-
Loubot over 7 yearsGave the +1. I had to change it to
rake db:migrate
-
Max Woolf over 7 yearsyeah, Rails 5 replaces
rake
globally with therails
binary. I'll update my answer. -
Loubot over 7 yearsCheers for that. Haven't moved to rails 5 yet.
-
hajpoj over 7 yearsdocs: devcenter.heroku.com/articles/release-phase Note release phases are in Beta and the commands run when a new release is created (ie 1. an app build 2. a pipeline promotion 3. a config var change 4. a rollback 5. a rlease via the Platform API)
-
Mark Swardstrom over 2 yearsDon't forget to add
-a appname
if you have more than 1 app referenced in git remotes