DEV Community

Cover image for Multiple environments with Heroku and Git
Paula Santamaría for Uppernauts

Posted on • Edited on

Multiple environments with Heroku and Git

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

👆 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
Enter fullscreen mode Exit fullscreen mode

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

git push remote-name branch-name
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

    heroku create myAppName --remote heroku-demo 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (4)

Collapse
 
acanimal profile image
Antonio Santiago

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.

Collapse
 
paulasantamaria profile image
Paula Santamaría

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

Collapse
 
amureki profile image
Rustem Saiargaliev

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.

Collapse
 
paulasantamaria profile image
Paula Santamaría

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.