Question

I'm considering paying the $50/ mo for a production database so I can use PostGIS with my rails 4 app. My issue is that I would like to continue developing with a 'staging' environment, but can't yet justify paying for two production databases. Staging is obviously just a clone of production, so just pointing both apps to the same DB url (post) would likely cause some major headaches.

Is there any way to partition the database, or another strategy you'd recommend?

Initial answer from heroku support is no, but I'm hoping there's a scrappy workaround.

Thanks!

Was it helpful?

Solution

First off, I would highly suggest just paying the extra $50/mo. For that, you get all kinds of cool stuff like forking and pipelines, as well as the fact that this is kind of hacky. I honestly don't know if this might end up wiping your production data when you clear the staging database. Please make backups before trying this.

I'll view this answer as an answer to a technical challenge rather than a business decision. Without further ado,

Setting up multiple environments on the same database with Heroku Postgres schemas

First, I deleted the existing dev database and added a production database to my production app.

heroku addons:add heroku-postgresql:crane

> Adding heroku-postgresql:crane on test-shared-app... done, v# ($50/mo)
> Attached as HEROKU_POSTGRESQL_RED_URL

This attached a database under the RED color, so replace HEROKU_POSTGRESQL_RED_URL with the appropriate color for your app.

This attaches a database to the production app, but we need to connect to the same app for staging. First, create the staging schema

heroku run "bundle exec rails runner 'ActiveRecord::Base.connection.execute(%q{CREATE SCHEMA staging})'"

Next, create the staging app. See Managing Multiple Environments for an App for more information.

heroku create --remote staging test-shared-app-staging
heroku config:set RACK_ENV=staging RAILS_ENV=staging --remote staging

Then, copy the environment data from your existing app. Add ?schema_search_path=staging to the end of the URL.

heroku config --remote heroku --shell
# make note of your database URLs
heroku config:set --remote staging \
  DATABASE_URL=postgres://...?schema_search_path=staging \
  HEROKU_POSTGRESQL_RED_URL=postgres://...?schema_search_path=staging

And push to staging

git push staging master

Now, run migrations on staging

heroku run --remote staging bundle exec rake db:migrate

And try it out.

My "app" is running at http://test-shared-app.herokuapp.com/posts and http://test-shared-app-staging.herokuapp.com/posts. You can see the source at https://github.com/benmanns/heroku-shared-app.

OTHER TIPS

If I were you, I would use production DB until the right moment (start making money or getting more users, etc). I would replicate all the tables in production DB and give the new tables new names by prepending something like "stag_{original_table_name}. So, you would have two different sets of the same tables. In your models, make them use the new table on staging environment:

class Foo < ActiveRecord::Base
  self.table_name = "staging_#{self.class.name}" if Rails.env.staging?

I am pretty cheap... and this may be an ugly solution in the eyes of the true Rails masters.

Heroku Schemas is another approach to this; it's a Heroku plugin that basically lets you run a single command to apply Benjamin Manns's solution of multiple schemas.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top