How to deploy multiple apps in a monorepo with Heroku

Laurent Grima
inato
Published in
3 min readSep 5, 2018
Photo by Twixes on Unsplash

At Inato, all our web apps are contained in one monorepo (front-end apps, APIs, …). We use yarn workspaces to manage all of these packages.

To host and run our apps, we use Heroku.

The standard Heroku setup only works for the 1-app-1-repo use case.

So, here is a quick guide on how to host and run multiple apps from multiple yarn workspaces contained in a single Git repository on Heroku.

Disclaimer: this guide assumes a basic knowledge of Heroku (See Getting Started).

Let’s say you have a single Git repository containing multiple applications in yarn workspaces like so:

.
├── package.json
├── packages
│ ├── web-client
│ │ └── package.json
│ └── api
│ └── package.json
└── scripts
└── heroku.build

Both web-client and api are web applications that need to be exposed to the network.

Using a single Procfile to expose several web processes is not possible on Heroku. You won’t be able to have api and web in a Procfile both exposing web apps. I.e. this does not work:

web: yarn workspace web-client start
api: yarn workspace api start

The web process type is special as it’s the only process type that will receive HTTP traffic from Heroku’s routers. Other process types can be named arbitrarily.

from the Heroku documentation.

The proper way to do it is to:

  • Create one dyno for each app (workspace) you want to run
  • Use the multi-procfile buildpack
  • Optionally use environment variables to tweak your build step

Here’s the detail:

1. Create one dyno for each app (workspace) you want to run

Create one named Heroku app per web app using the Heroku CLI and bind it a Git remote.

$ heroku create web-client --remote heroku-web-client
$ heroku create api --remote heroku-api

Here,web-client is the name of the Heroku app and will make the app available at http://web-client.herokuapp.com, while heroku-web-client is the name of the git remote pointing to this heroku app and makes it possible to deploy your code to one app or the other like so:

$ git push heroku-web-client master

2. Use the multi-procfile buildpack

You need to tell Heroku how to run each of your apps. There is a buildpack provided by the Heroku team exactly for this: Heroku Multi Procfile buildpack.

Imagine you have a single code base, which has a few different applications within it… or at least the ability to run a few different applications. Or, maybe you’re Google with your mono repo?

In any case, how do you manage this on Heroku? You don’t. Heroku applications assume one repo to one application.

Enter the Multi Procfile buildpack, where every app gets a Procfile!

- Write a bunch of Procfiles and scatter them through out your code base.

- Create a bunch of Heroku apps.

- For each app, set PROCFILE=relative/path/to/Procfile/in/your/codebase, and of course: heroku buildpacks:add -a <app> https://github.com/heroku/heroku-buildpack-multi-procfile

- For each app, git push git@heroku.com:<app> master

For our example, we would have one Procfile per workspace:

.
├── package.json
├── packages
│ ├── web-client
│ │ ├── Procfile
│ │ └── package.json
│ └── api
│ ├── Procfile
│ └── package.json
└── scripts
└── heroku.build

containing for instance:

web: yarn workspace api start

3. Optionally use environment variables to tweak your build step

By default, Heroku only installs Node and runs yarn install (what it calls the “build” step). If you actually need to build something (like your front-end bundle), you can use heroku-postbuild for Heroku-specific tasks (documentation), which is goes in the scripts section of your top-level package.json.

Using environment variables, you can make this script accomplish different things depending on the app.

Exemple:

top-level package.json
./scripts/heroku.build

That’s it !

With those steps, you can build and run different apps from your monorepo.

--

--

Laurent Grima
inato
Writer for

I write about product design & management • Work with me: https://laugri.com • 🏄‍♂️ 🥘 🪴