loading...
Cover image for Multiple environments with Heroku and Git
Uppernauts

Multiple environments with Heroku and Git

paulasantamaria profile image Paula Santamaría Updated on ・4 min read

I've been using Heroku as a dev environment to work with my team for the last few months. It was going great until last week our client asked for a live demo 😱.
We couldn't do a demo on a dev env, mainly because we can't ask our team to stop working during the demo (and we all know dev environments are usually filled with cat pics, "tests" and "lorem ipsums"), so we decided to create a "demo" env.
I went straight to the Heroku docs to figure out how to handle multiple environments. In this post I'll try to cover everything I learned on the subject.

Git remote

The first thing we need to understand is git remote.
Taken from the GitHub docs:

A remote URL is Git's fancy way of saying "the place where your code is stored."

You can run this command to check which remotes you have configured in your project:

git remote -v

In your typical project the output would be something like this:

> origin https://your-git-repo/your-git-project (fetch)
> origin https://your-git-repo/your-git-project (push)

👆 In this case your-git-project only has 1 remote configured and it's called "origin".

(you can also check your project's remotes under your-git-project/.git/config)

In case you want to dig more into it, here's the GitHub doc about Managing remotes

Multiple remotes

So as you may have guessed, your git project can handle multiple remotes, which means you can push your code to any existent remote.

To add a new remote to your project:

git remote add remote-name https://your-git-repo/your-git-project.git

And to push your code to a specific remote and branch:

git push remote-name branch-name

So what about Heroku?

When we create a Heroku app using the Heroku CLI, it automatically adds the remote to our new app for us. In fact, if you check the logs you'll see something like this:

> Git remote heroku added

Taken from Heroku's documentation:

When you create an application on Heroku, it associates a new Git remote, typically named Heroku, with the local Git repository for your application.

So the Heroku CLI takes care of adding a remote called "heroku" into your git config. My recommendation would be to replace that name for something that reflects the remote's purpose more accurately, especially if you're going to use Heroku to handle more than one environment of your app.

Update Heroku's remote name

To set up a better name for your Heroku remote, run this command:

git remote rename heroku heroku-dev

Specify the remote name when creating a Heroku app

You can also define a better remote name first hand when creating the app, like this:

heroku create myAppName --remote heroku-dev

Config Vars

There's one more thing. Your app needs to know to which env it's been deployed, and that's when Config Vars come in. Config variables can be accessed from our code and used to figure out which env it's in and, for example, access that particular environment's database (you don't want your dev environment making inserts into your demo database).

We can easily add a new config var from the Heroku CLI, like this:

heroku config:add ENV="dev" --remote heroku-dev

E.g: Here's a simplified example of how I manage different connection strings for each environment with Node.js, MongoDB and config vars:

// config.js
const config = {
    dev: {
        connectionString: "mongodb://my-DEV-db-connection-string"
    },
    demo: {
        connectionString: "mongodb://my-DEMO-db-connection-string"
    }
}

// app.js
const config = require('./config').get(process.env.NODE_ENV);
const mongoose = require('mongoose');
mongoose.connect(config.connectionString, { useMongoClient: true });

Check out the Heroku docs to learn More about Config vars

Summary

How to create multiple environments for a new app :

1- Create a Heroku app for every environment you need, and specify a remote name for each one.

    heroku create myAppName --remote heroku-dev
    heroku create myAppName --remote heroku-demo 

2- Setup a config var for each env to let your app know where is running

    heroku config:add ENV="dev" --remote heroku-dev
    heroku config:add ENV="demo" --remote heroku-demo 

In case you already have your dev environment running in Heroku and want to add new envs:

1- Rename your current Heroku remote (optional):

    git remote rename heroku heroku-dev

2- Create a Heroku app for the new environment, specifying a new remote name:

    heroku create myAppName --remote heroku-demo 

3- Setup a config var for each env to let your app know where is running:

    heroku config:add ENV="dev" --remote heroku-dev
    heroku config:add ENV="demo" --remote heroku-demo 

Now push!

Now that our remotes are all setup, we can push our changes to the demo env, like so:

    git push heroku-demo master

Heroku will now retrieve any dependencies our project needs and build it for us so we can have our app online almost instantly.

That's it!

Hope this helps someone, thanks for reading!

Posted on Oct 25 '18 by:

paulasantamaria profile

Paula Santamaría

@paulasantamaria

Passionate about creating stuff. Gamer, digital artist and guitarist on my free time.

Uppernauts

Uppernauts is a Software development company based in Buenos Aires, Argentina. We create secure software solutions working alongside our users to guarantee the best user experience.

Discussion

markdown guide
 

Nice article ! My unique comment is better deploy through a CI/CD tool than manually.

We also work with heroku and have different environment but have configured the deploys via gitlab-ci to be automatics.

 

Sounds interesting, thanks! I’ll definitely look into it.

 

Hey there!

Thank you for the article!

I wanted to share my experience with similar cases, where we do need to share some stuff with stakeholders/users, we are started using review apps feature from Heroku: devcenter.heroku.com/articles/gith...

This is very handy when you need to create a fully-working app (production-like), based on some feature branch (PR).

So, any time we need to show some work done, we fire up a review app, then just providing the link to the users. After the feature reviewed/tested/merged, review app got automatically deleted.

 

I didn't know about this feature, so cool!
Thanks for sharing. I'm currently using Free dynos, so this feature might not be available, I'll have to do some digging.