30

Within one git repo, I have two separate applications (web server and API server).

How can I deploy each application to its own Heroku app?

(So there are 2 heroku apps, one for the web server and one for the api server)

Note (before marking as duplicate): There are several questions similar to this. Most deal with deploying one app to two heroku apps - typically for the purpose of staging vs. production. I am looking to deploy two apps to two heroku apps. (Question about staging vs prod)

Community
  • 1
  • 1
Don P
  • 60,113
  • 114
  • 300
  • 432

6 Answers6

27

The solution suggested by rdegges unfortunately does not work anymore. See:

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. So you won't be able to have api and web in a Procfile both exposing web apps.

Up-to-date solution

The correct way to tackle this is to use this buildpack provided by the Heroku team: 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!

I've been using this buildpack for multiple months now on a repository using yarn workspaces (multiple Node and React apps in one repo) and everything works fine.

laugri
  • 597
  • 6
  • 13
  • Hello, Could you please explain the following step: "For each app, set PROCFILE=relative/path/to/Procfile/in/your/codebase, and of course: heroku buildpacks:add -a https://github.com/heroku/heroku-buildpack-multi-procfile" I have 2 procfiles, one is in the root and another is under the backend folder. procfile1 = web: npm run build procfile2 = api: node backend/server What exactly does in mean "For each app, set PROCFILE=relative/path/to/Procfile/in/your/codebase" What needs to be done here? Thanks – danikoren Oct 01 '18 at 18:36
  • 1
    @danikoren Here `PROCFILE` refers to an environment variable. You can read more about it here in the Heroku doc: https://devcenter.heroku.com/articles/config-vars#managing-config-vars You would need to have two Heroku apps, one for your front-end and one for your back-end, and set the `PROCFILE` env variable to the path of each Procfile respectively. I wrote an article with a bit more details here: https://medium.com/inato/how-to-setup-heroku-with-yarn-workspaces-d8eac0db0256 Let me know if this helps. – laugri Oct 01 '18 at 22:08
  • Thanks! What is the sequence of starting all of the apps? Do I just run "git push heroku master" and both procfiles will run? I don't seem to get my backend app to run. – danikoren Oct 03 '18 at 21:30
  • how about the slug, do they share the same one? – Jalal Sordo Dec 30 '20 at 22:01
20

My understanding of your question is that you have one Git repository, that contains two entirely separate programs: one API server, and one web server.

With this assumption in mind, here's what you'll want to do, step-by-step:

  1. Go into your project folder.
  2. Define a Procfile at the root of your project. This will tell Heroku how to run your web server and your API server.

Here's how you might want your Procfile to look (an example):

web: node web/index.js
api: node api/index.js

In my example above: I'm defining two types of Heroku dynos -- one called web and one called api. For each one, you'll need to tell Heroku what command to run to start the appropriate server. In this example, I would run node web/index.js to start up my website, and node api/index.js to start up my API service.

  1. Create two new Heroku applications. You can do this by running heroku create <desired-app-name> --remote <desired-app-name> multiple times. NOTE: The --remote flag will tell Heroku to create a Git remote for each of your applications in the same repo.

  2. Next, you'll need to tell Heroku to run your actual web application on one Heroku app, and your API service on another Heroku app. You can do this by using the Heroku CLI:

    $ heroku ps:scale web=1 --remote webserver-app-name
    $ heroku ps:scale api=1 --remote apiserver-app-name
    

These commands will:

  • Run a single web dyno for your webserver Heroku app.
  • Run a single API dyno for your apiserver Heroku app.

As you can see above, using the ps:scale command you can control what types of commands Heroku will run from your Procfile, and how many instances of each you'd like to have.

Hopefully this helps!

rdegges
  • 32,786
  • 20
  • 85
  • 109
  • Thanks rdegges, I'll give this a try today. Question though - will I just do `git push heroku-api master` and `git push heroku-web master` to push my master branch to each separate heroku app? – Don P Jan 04 '17 at 18:31
  • 2
    Ah, when you want to push your mast branch you'll do: `git push heroku-api master; git push heroku-web master;` to deploy it to both projects =) Instead of the usual `git push heroku master` you'll do this, because instead of the `heroku` remote you now have two remotes: `heroku-web` and `heroku-api`. Hope that makes sense! – rdegges Jan 04 '17 at 18:58
  • This is great, but you need to somehow install dependencies too. I did that by putting `npm install` in the script to run my apps from subfolders. Isn't perfect, but I don't know how to do it on push. – Piotr Buda May 23 '17 at 15:09
  • You don't have to do that. It will install them automatically upon push. – rdegges May 23 '17 at 15:32
  • 3
    @rdegges This doesn't work for me because Heroku says there is no `web process type`. How can I tell Heroku that for example, `api` is my web process type for an app? – Sergio Tapia Sep 05 '17 at 19:37
  • This can't work, because Heroku allows only `web` to receive incoming requests, eg act as a http server. I am also now struggling to figure it out. But this is not the way. – Popara Nov 21 '17 at 09:36
  • 2
    Heroku recently changed their behavior, it appears. This used to work. It looks like doing this now requires you to have two separate Procfiles entirely. – rdegges Nov 22 '17 at 17:58
9

If you have two separate application then you can simply push repository sub-tree to each.

Setup remotes once

heroku git:remote --remote heroku-client -a client-app
heroku git:remote --remote heroku-server -a server-app

And then you can deploy through pushing sub-tree to the remote

git subtree push --prefix client heroku-client master
git subtree push --prefix server heroku-server master

(where --prefix points to app's root folder)

farincz
  • 4,943
  • 1
  • 28
  • 38
0

We can add to the customized script to deploy a particular folder in our git directory to our npm scripts in the package.json file. Check the below code in the package.json file

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

then you can run npm run-script publishheroku to deploy.

Also, go through this link for detailed explanation.

Kapil Raghuwanshi
  • 867
  • 1
  • 13
  • 22
0

Due to the fact that Heroku doesn't allow more than one Procfile and it should have only one web key for HTTP traffic and port allocations. So, that's how I overcome this limit (Dynamic entry point through env vars)

  • Assuming we have two Heroku apps, define an envireonment variable for each entry point at both apps.

    • App 1: INDEX_PATH='./1/index.js'
    • App 2: INDEX_PATH='./2/index.js'
  • Create Procfile with the following contents

web: npm run start-heroku
  • At `package.json, add the following script
"start-heroku": "node heroku.js",
  • Create heroku.js with the following contents
const Path = require('path')

require(Path.join(__dirname, process.env.INDEX_PATH))

Now, when we deploy App 1, Heroku will execute Procfile (web) that will execute heroku.js and based on INDEX_PATH env var, the target app will start!

Mouneer
  • 12,827
  • 2
  • 35
  • 45
-2

I faced a similar issue. In my case, I had a single GitHub repo with a React front end in a folder and an API in another folder.

After a bit of googling, I found a buildpack that let me deploy sub-folders on Heroku. I used the buildpack and created a couple of projects on Heroku to deploy both the API and the React Front End.

The buildpack is https://github.com/timanovsky/subdir-heroku-buildpack

I wrote a step-by-step article along with screenshots in the below article.

https://www.realpythonproject.com/how-to-setup-automated-deployment-for-multiple-apps-under-a-single-github-repository-in-heroku/

  • 1
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it is there, then quote the most relevant part of the page you are linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](/help/deleted-answers) – jmoerdyk Nov 30 '21 at 19:26
  • Thank You for the feedback! I will update my answer. – Rahul Banerjee Nov 30 '21 at 19:29
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/30472906) – aerial Dec 01 '21 at 06:45