node-js

in Web

How to Deploy to Multiple Heroku Apps from the Same Git Repository

I have been using Heroku for various projects for a while now, and it is a great option for hosting Node.js apps. One unique item about Heroku is that it manages app deployments with Git.

Using Git to deploy your app may take a little getting used to at first, but assuming you are already using Git for your project’s source control management (and you should!) then the process is fairly straightforward: add a new remote pointing to Heroku, and when ready to deploy, commit your changes and then push to that remote.

But what happens when a repo has more than one Heroku app?

I recently needed to migrate some existing apps to Heroku from a different hosting platform. These apps are being kept as subdirectories in a single repository. This wasn’t an issue on the previous host, as I could just run their deploy command for each app and specify the directory where it was located, and everything was good to go, however, as mentioned above, you deploy to Heroku with git.

There were a couple of issues with my setup preventing me from deploying the Node.js apps to Heroku:

  1. I have a single repository that will need to publish to multiple Heroku apps
  2. The individual Node apps are kept in subdirectories, so I’ll need to publish just that subdirectory to heroku

The layout looks something like this:

repo/
├──nodeapps/
   └── appone/
   └── apptwo/

...other folders and files

Fortunately, the workaround is fairly straightforward. There are just two extra steps you need to do to set up a repo to deploy to multiple Heroku apps.

Step 1. Add and/or Rename Your Heroku Remotes

If you create a heroku app via their CLI using heroku create a remote called heroku will be automatically created for you in your git settings.

If you have already created your Heroku app, say, via their web dashboard, then you can use the heroku cli to set up the remote in your local repo with:

heroku git:remote -a my-heroku-app-name

See more here.

In either case, a remote called heroku will be created. This is fine if you are just deploying to a single Heroku app, but we need multiple remotes pointing to different Heroku apps. To get around this, we just need to rename the heroku remote to something else before we add the second remote.

We can do something like this:

cd repo

# add the first remote
heroku git:remote -a app-one-name
#set git remote heroku to https://git.heroku.com/app-one-name.git

#next, rename the remote to something else
git remote rename heroku heroku-app-one

#now we can add second remote for our other app

heroku git:remote -a app-two-name
#set git remote heroku to https://git.heroku.com/app-two-name.git

#doesn't hurt to rename this one as well
git remote rename heroku heroku-app-two

Now, we will have two remotes (in addition to any remote pointed to github, bitbucket, etc)

Step 2. Set up a Script to publish just the node app directory to the correct Heroku remote

We have the remote names sorted, now we need to have a way to push just the sub directory in our repo that contains our node app to to the correct remote.

Since we are building node.js apps, we can use npm as a build tool to help us publish to our Heroku remotes.

As mentioned previously, we are keeping our node apps in our repo under repo/nodeapps/appone and apptwo. Inside each of these folders, we have our typical node.js structure, including a package.json file. We can use that to perform the necessary commands to publish just our subfolder to the correct remote.

Inside package.json look for the scripts property:

...
"scripts": {
    "start": "node app.js"
  },
...

You probably have one or more scripts set up so you can run npm start to launch your app, for example. We can add a custom one here to handle publishing to heroku, so let’s do:

"scripts": {
    "start": "node app.js",
    "publishheroku": "cd ../../ && git subtree push --prefix nodeapps/appone heroku-app-one master || true"
  },

Let’s break down that publishheroku script:

  1. cd ../../ – Go up two folder levels to to the root of our repo. This is where our git is configured.
  2. && git subtree push --prefix nodeapps/appone – Execute the git command subtree to push just the specified subfolder/li>
  3. heroku-app-one master – The name of our new remote and the name of the branch to be pushed.
  4. || true – This just suppresses that annoying npm error code

After this, you can repeat Step 2 for nodeapps/apptwo/package.json taking care to update the app directory and remote name!

Running It!

Okie dokie, now we can use npm to deploy to heroku!

cd nodeapps/appone
npm run-script publishheroku

Caveats

  • This assumes you are using npm as a build tool, though the same should work for any other tool, provided you can execute a script with it.
  • If you need to publish a branch other than `master`, you will need to make the appropriate change in the `publishheroku` script by replacing `heroku-app-one master` with `heroku-app-one otherbranch`

That’s it! I hope you find this useful.