Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GIt Deployment + Configuration Files + Heroku

I'm using Heroku to host a Rails app, which means using Git to deploy to Heroku. Because of the "pure Git workflow" on Heroku, anything that needs to go upstream to the server has to be configured identically on my local box.

However I need to have certain configuration files be different depending on whether I'm in the local setup or deployed on Heroku. Again, because of the deployment method Heroku uses I can't use .gitignore and a template (as I have seen suggested many times, and have used in other projects).

What I need is for git to somehow track changes on a file, but selectively tell git not to override certain files when pulling from a particular repo -- basically to make certain changes one-way only.

Can this be done? I'd appreciate any suggestions!

like image 227
Andrew Avatar asked Jan 31 '11 22:01

Andrew


People also ask

How do I deploy a Git repo to Heroku?

To deploy your app to Heroku, use the git push command to push the code from your local repository's main branch to your heroku remote. For example: $ git push heroku main Initializing repository, done.

How does Heroku work with Git?

Git is a powerful, distributed version control system that many developers use to manage and version source code. The Heroku platform uses Git as the primary means for deploying applications (there are other ways to transport your source code to Heroku, including via an API).

Is Heroku integrated with Git?

Heroku integrates with GitHub to make it easy to deploy code living on GitHub to apps running on Heroku. When GitHub integration is configured for a Heroku app, Heroku can automatically build and release (if the build is successful) pushes to the specified GitHub repo.


2 Answers

You can have config vars persistently stored ON each heroku app's local setup so they do not have to be in your code at all! so the same code can run on multiple heroku sites but with different configuration. It very simple, easy, elegant...

It's the approach we used. (We used it for the SAME thing... we have multiple clones of the SAME app at Heroku, but we want only ONE source at github, in our dev local directory we do the PUSH to ORIGIN (github), then when we have it the way we like it, we CD to the prod local directory, which goes to the SAME github repository, and we ONLY PULL from GITHUB into this directory, never push (eg, all pushes to github come from our dev directory, the prod directory is just a staging area for the other heroku app.)

By having the different configs ON the different HEROKU sites (as explained below), the EXACT SAME CODE works on BOTH heroku sites.

So our workflow is: (the key is that BOTH directories point to SAME github repo)

cd myDEVdir
*....develop away....*
git add .
git commit -am "another day, another push"
git push origin  *(to our SINGLE github repo)*
git push heroku  *(test it out on heroku #1)*

cd ../myPRODdir
git pull         *(grabs SAME code as used on other site *)
git push heroku  *(now the SAME code runs on Heroku #2)*

that's it!

Now here's how you keep your site-specific config vars ON the heroku site:

http://docs.heroku.com/config-vars

on your local command line, for EACH of your two local directories, do:

$ heroku config:add FIRST_CONFIGVAR=fooheroku1
Adding config vars:
  FIRST_CONFIGVAR => fooheroku1

$ heroku config:add SECOND_CONFIGVAR=barheroku1
Adding config vars:
  SECOND_CONFIGVAR => barheroku1

to see the ones you have defined:

$ heroku config
FIRST_CONFIGVAR => fooheroku1
SECOND_CONFIGVAR => barheroku1

then cd to your other directory myPRODdir and do the SAME thing, only set the same remote heroku vars to fooheroku2 and barheroku2.

then in your rails app you simple refer to them like so:

a = ENV['FIRST_CONFIGVAR']

One app will read 'fooheroku1' the other app will read 'fooheroku2'

And finally, on your LOCAL directory myDEVdir, where you run in DEV mode, put the same config commands in your config/environment/development.rb file your 'dev' version of the config vars will be set to whatever they should be:

ENV['FIRST_CONFIGVAR'] = "foodev"
ENV['SECOND_CONFIGVAR'] = "bardev"

Easy, elegant. Thanks, Heroku!

like image 155
jpw Avatar answered Sep 20 '22 10:09

jpw


Here are a few solutions:

1) If you want to ignore files only on heroku, use slugignore

2) If your changes are minor, stay DRY and use universal config files, inserting switches for server-specific behavior

if Rails.env == "production"
    #production server code
elsif Rails.env == "development"
    #development server code
else
    #test server code
end

3) If your changes are major, write one config file and add a "smudge file" to config/initializers for each additional server. Basically, you would have separate files using the technique in (2).

4) If your changes are SWEEPING (unlikely), then maintain separate branches for each server.

5) This script can do exactly what you requested, but may be overkill.

I hope that helped.

like image 28
jaime Avatar answered Sep 20 '22 10:09

jaime