Using Heroku to work with multiple environments can be pretty easy.
The heroku
tool can look at your git remote
s to decide which
app should receive the API commands.
You probably have just a single remote for your local repo: origin
.
It's the Github repo where the code lives. We won't be touching it.
All the git push
and git pull
commands you use will continue to
work against this repo.
$ cd myapp
$ git remote -v # Look at your existing remotes
origin https://github.com/ghuser/myapp.git (fetch)
origin https://github.com/ghuser/myapp.git (push)
It's pretty typical to have separate environments for production and staging or test, but over time you'll probably expand to more.
With this default setup, you have to specify which app you're working on
with the -a, --app APP
option:
$ heroku ps --app myapp-prod # Type full app name: myapp-prod
=== web: `./node_modules/.bin/startup start --cluster`
web.1: up 2013/03/12 10:53:43 (~ 11m ago)
web.2: up 2013/03/12 10:53:43 (~ 11m ago)
$ heroku ps -a myapp-test # Type full app name: myapp-test
=== web: `./node_modules/.bin/startup start --cluster`
web.1: up 2013/03/12 11:04:35 (~ 42s ago)
It doesn't take long for it to get tedious to type the app name in over and over. It's also confusing when you have many apps on Heroku and you tend to have a similar setup for each of them (which app am I in again?).
It'd be easier if you could always type prod
when you're in the app's
directory and have it just know which Herkou app you're talking about.
You can connect the codebase of your app to each of its deployments on Heroku. Remember, each environment has its own config settings, even if they run the same code.
To start with, let's add some remote references to prod
and test
as
shortcuts. The Heroku app name is also it's git repo name.
$ git remote add prod [email protected]:myapp-prod.git # Add standard deployments
$ git remote add test [email protected]:myapp-test.git
So now I have a remote prod
connected to my app myapp-prod
and
a remote test
connected to myapp-test
.
It can be helpful to have a deployment for your own code. You can pick
any name for it. Here I use mine
.
$ git remote add mine [email protected]:myapp-timshadel.git # Add personal deployment
Here's how you list all the remotes you have for a given codebase. Notice that both your source code management remotes (Github) and your app deployment remotes (Heroku) are mingled together in this list.
$ git remote -v # Checkout the git setup
mine [email protected]:myapp-timshadel.git (push)
mine [email protected]:myapp-timshadel.git (fetch)
origin https://github.com/ghuser/myapp.git (fetch)
origin https://github.com/ghuser/myapp.git (push)
prod [email protected]:myapp-prod.git (push)
prod [email protected]:myapp-prod.git (fetch)
test [email protected]:myapp-test.git (fetch)
test [email protected]:myapp-test.git (push)
Now that we've got setup the git remote
s, let's use them with the
heroku
command via the -r, --remote REMOTE
option. It's like
using the -a, --app APP
option, but instead it figures out the
app name from your git remote
.
Here's what it's like to check on all the processes for each of your app deployments:
$ heroku ps -r prod # Uses myapp-prod
=== web: `./node_modules/.bin/startup start --cluster`
web.1: up 2013/03/12 10:53:43 (~ 11m ago)
web.2: up 2013/03/12 10:53:43 (~ 11m ago)
$ heroku ps -r test # Uses myapp-test
=== web: `./node_modules/.bin/startup start --cluster`
web.1: up 2013/03/12 11:04:35 (~ 42s ago)
$ heroku ps -r mine # Uses myapp-timshadel
=== web: `node runner.js`
web.1: idle 2012/07/11 18:36:31
Once you start using this pattern, the commands you type don't
change when you work with another app. Here's anotherapp
:
$ cd anotherapp
$ heroku ps -r prod # Uses anotherapp-prod
=== web: `./node_modules/.bin/startup start --cluster`
web.1: up 2013/03/12 09:53:43 (~ 1h ago)
web.2: up 2013/03/12 09:53:43 (~ 1h ago)
$ heroku ps -r test # Uses anotherapp-test
=== web: `./node_modules/.bin/startup start --cluster`
web.1: up 2013/02/12 11:04:35 (~ 1 month ago)
$ heroku ps -r mine # Uses anotherapp-timshadel
=== web: `node runner.js`
web.1: idle 2012/09/11 18:36:31
The big benefit from this pattern is how easily you can work with a large number of apps while letting your muscle memory keep the same keystrokes no matter which app you use.
The -r, --remote REMOTE
option is global, so every heroku
subcommand, including those installed by plugins, will work
with it.
Happy DevOps-ing!
I've also found it useful at times to open up a bash prompt to my heroku app so I can see what files are really there and how things got deployed. It's pretty simple as well:
That should give you a bash prompt to your heroku app. Be aware that heroku actually starts-up a new instance of your app and then gives you a prompt to that new instance. You can't actually touch your running web process using this method.