It’s currently not possible to do an automated migration from or to the “Heroku Celadon Cedar Stack”:http://devcenter.heroku.com/articles/cedar which “started in May”:http://blog.heroku.com/archives/2011/5/31/celadon_cedar/. The only help that you get from Heroku is this:
Migrating From Bamboo to Cedar
Before migrating to Bamboo, you should make sure your app runs on Ruby 1.9.2. If your app is not already deployed successfully to bamboo-mri-1.9.2, you should do that first, and then come back and try Cedar.
Once you’re sure your app is fully compatible with Ruby 1.9.2, create an app on the Cedar stack and push to it. Currently, stack:migrate does not work for moving apps to Cedar.
Since there seem to be no blogposts of how to do all the stuff with an existing application I will try to cover everything that I did to do the migration manually in this article.
h2. Cedar is different
If you are looking at the new stack you will notice that a lot has changed with Cedar. Most of the “Heroku CLI”:http://devcenter.heroku.com/categories/command-line has changed to reflect the new possibilites that come with the Cedar stack. Since Cedar introduces a new “way of handling processes on Heroku”:http://devcenter.heroku.com/articles/process-model, most of the commands are now streamlined with this:
# old
heroku console
heroku rake db:migrate
# new
heroku run console
heroku run rake db:migrate
# have a look at running processes
heroku ps
# look at logs of different processes and tail the output
heroku logs --ps web -t
h3. Preparing the Migration
I started by cloning my current app from Heroku into another directory and creating a new Cedar app on Heroku:
git clone [email protected]:hamburg-on-ruby.git legacy
cd legacy
heroku create --stack cedar
h3. Adapting Cedar changes
The “docs for creating a Rails 3 app on Cedar”:http://devcenter.heroku.com/articles/rails3 reflect some of the changes that have been introduced with Cedar.
One of those is that PostgreSQL is now recommended for local development and you need to have the “pg-gem”:https://rubygems.org/gems/pg in your Gemfile. Otherwise you will get errors while running rake commands:
heroku run rake db:migrate
Running rake db:migrate attached to terminal... up, run.1
(in /app)
rake aborted!
no such file to load -- pg
Since I developed my app with SQLite3 and I don’t want to learn, install and manage ANOTHER Database I split up the database stuff for development, test and production:
# Gemfile
group :production do
gem "pg"
end
group :development, :test do
gem "sqlite3-ruby", :require => "sqlite3"
end
and exclude production dependencies from my local environment:
# put this into your .profile
alias bd="bundle --without=production"
It’s also recommended to serve Rails through “thin webserver”:https://rubygems.org/gems/thin and manage the application with “the Procfile manager foreman”:https://rubygems.org/gems/foreman:
# Gemfile
gem "foreman"
gem "thin"
# Procfile
web: bundle exec rails server thin -p $PORT
foreman start
After going through those chages you should be able to see your application on localhost:
open http://localhost:5000
h2. The migration process
If the application is running on your development machine you can start the core migration process by putting your legacy application into maintenance mode, so that no database changes will be made:
heroku maintenance:on
# stop worker, crons or whatever might be changing the db
h3. Database Migration
After you completely halted everything on your dyno, you can start dumping the database to your development machine (I thought it would be neat to do a direct migration from the legacy database to the new Cedar database, but I did not get it working). You need to install the “taps-gem”:http://devcenter.heroku.com/articles/taps in order to do any dumping. Taps will dump the database into your development database unless you provide an connection string to another database:
# use sqlite for dumping and do it into a separate file
heroku db:pull sqlite://dump.db
# mv the file to your Cedar application and push it
heroku db:push sqlite://dump.db
h3. Config variables
If you have custom config variables in your application it’s pretty easy to move them into the new environment:
# list all config values of the legacy app in console format
heroku config -s
# replace the newlines with whitespaces and
# append all the configuration variables of
# your new Cedar app at the end or remove the
# ones that you do not want to migrate!
# add the list of values to your Cedar app
heroku config:add KEY=VALUE KEY2=VALUE2 [...]
h3. Installing addons
It’s also most likely that you want to use the same addons than in your legacy application:
# list your addons in the legacy app
heroku addons
# install all addons separately in the Cedar app
heroku addons:add apigee:basic
heroku addons:add cron:daily
[...]
h4. Sendgrid
If you are using “the Sendgrid Addon”:http://devcenter.heroku.com/articles/smtp#sending_email_from_rails you should be aware that the automatic configuration is not working anymore the Cedar Stack! You need to “configure it in your app”:http://devcenter.heroku.com/articles/smtp:
# config/environments/production.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
:address => "smtp.sendgrid.net",
:port => "25",
:authentication => :plain,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => ENV['SENDGRID_DOMAIN']
}
h3. Switching domains
Before you do the last step, you should have a look if everything is up and running:
heroku open
If everything is fine, you can move all the domains from the legacy application to your new and shiny Cedar Stack application:
# list domains in legacy app
heroku domains
# and remove them
heroku domains:remove hamburg.onruby.de
heroku domains:remove onruby.de
[...]
# re-add them to Cedar application
heroku domains:add hamburg.onruby.de
heroku domains:add onruby.de
[...]
Looking at “the result”:http://onruby.de is quite disappointing, because nothing has changed for the user, but everything is new and shiny from the inside!
If you have any other pointers of what you need to do for migrating your application please feel free to add a comment!
Thanks for the write-up. I found I needed to run ‘heroku restart’ as the final step after adding the domains as I was getting an error H14.
There are is a nice overview of some new features to be found here:
http://www.randomhacks.net/articles/2011/06/03/heroku-celadon-cedar-review
Pingback: Heroku Cedar Background Jobs for free! | ☠ nofail
Great writeup, thanks!
A nice trick for getting all the config vars on one line is `heroku config -s | xargs`
Thanks for the write up! It’s very useful.
You can actually skip the database migration step by just changing the DATABASE_URL of heroku config.
heroku config:add DATABASE_URL=
Hope that helps.
they finally created a guide for migration in the heroku docs http://devcenter.heroku.com/articles/cedar-migration
Hello,
I added a custom domain to my heroku app and it works well, however only on the top domain level. So, then when you click on any link on your website it opens up on it’s default subdomain like; appsubdomain.herokuapp.com
I setted CNAME record according to instruction https://devcenter.heroku.com/articles/custom-domains but still, it doesn’t work.
i think that you need to add the subdomains manually. perhaps it’s possible to use wildcards, but i did not test that.
here is the configuration i use:
> heroku domains
Domain names for hamburg-on-ruby.herokuapp.com:
http://www.onruby.de
onruby.de
hamburg.onruby.de
Nice examples, to migrate Google Apps see http://www.google.com/enterprise/marketplace/viewListing?productListingId=14156+5077282021820947710
I’d be very careful using the “heroku config:add DATABASE_URL=”-approach, as afaik you’d be connecting to the database of another app in your brand new cedar-app, how the fuck are you going to remember that in two years?
I just did it to test it out though, as nothing happened when I tried to push.
Great write up. I had a heroku problem where I accidentally deleted my heroku database, then tried to do heroku run rake db:migrate to recreate, but it failed, so I went with taps and pushed my local database to heroku and all is well. So, now my question is this: when I run migrations locally, do I have to run heroku run rake db:push, or should I be able to do heroku run rake db:migrate?
hi tom,
i don’t know. how about asking this question on stackoverflow?
kind regards,
peter
Good idea. Turns out the answer is yes, you can do heroku run rake db:migrate and the production db will only update migrations that have run since the last db:push.
http://stackoverflow.com/questions/11809624/can-i-run-heroku-run-rake-dbmigrate-after-using-taps-and-heroku-dbpush/11809757#11809757