Is it possible to deploy a Node.js application to Heroku without a web dyno?
Asked Answered
I

3

12

For some backstory and reference, here are some quotes from a few Heroku documentation pages.

From the Heroku Node.js Support > Activation:

The Heroku Node.js buildpack is employed when the application has a package.json file in the root directory.

From Heroku Node.js Support > Default web process type:

First, Heroku looks for a Procfile specifying your process types.

If no Procfile is present in the root directory of your app during the build process, your web process will be started by running npm start, [...]

From Process Types and the Procfile > Process types as templates:

A Procfile contains a number of process type declarations, each on a new line. Each process type is a declaration of a command that is executed when a dyno of that process type is started.

For example, if a web process type is declared, then when a dyno of this type is started, the command associated with the web process type, will be executed. This could mean starting a web server, for example.


I have a package.json file in the root (which will activate the Node.js buildpack), and I've also included a Procfile in the root with the following contents:

service: npm start

I would assume that not defining a web dyno would cause it to not be created; only the service dyno should be created, following the configuration declared in the Procfile.

Instead, what happened is that an active web dyno was automatically created using npm start and an inactive service dyno was created using the definition in Procfile. I then had to:

  • heroku ps:scale web=0
  • heroku ps:scale service=1

I can definitely imagine wanting to run a Node.js "service" application on Heroku that does not accept any incoming connections, only making outgoing ones. Is there a way to configure the Node.js buildpack to not automatically create a web dyno when one is not defined? I've looked through lots of documentation looking for a way to either: (1) define it as such or (2) remove the automatically generated web dyno; but, I haven't found anything.

Thanks for the help!

Isisiskenderun answered 26/10, 2016 at 14:59 Comment(0)
I
13

I ended up opening a helpdesk ticket with Heroku on this one. Got a response from them, so I'll post it here. Thanks Heroku support!


The short answer is that, no, currently you'll need to heroku scale web=0 service=1 in order to run a service without a public web process. For a longer explanation:

Early on, the Node.js Buildpack checked for the presence of a Procfile and, if missing, created a default one with web: npm start. This made it easy to create apps without a web process, since you could just provide a Procfile that defined some processes, omitting web from the list.

However, as more and more users needed arrays of buildpacks instead of a single one, that solution created issues. Node is the most popular first buildpack, since it's frequently used by Java, Python, PHP, and Ruby apps to build front-end assets. Whenever an app without a Procfile ran Node first, and another buildpack second, Node would inject its own default Procfile (web: npm start), and the second buildpack would then not create its default Procfile as one already existed in the filesystem. So injecting a default Procfile when one is missing from the app creates problems downstream for multilingual apps.

So, we stopped creating a default Procfile and instead used default_process_types in bin/release. This fixes the issue of subsequent buildpacks inheriting incorrect default Procfiles, but since default_process_types is extended rather than replaced by the Procfile process list, apps without a web process defined in their Procfile will get the default web process merged in. This is why web appears even without a web entry in Procfile.

We also don't want to surprise any customers with unexpected bills. Some apps have many process types, some of which are only to be run occasionally, some limited to a single instance, some which need to be scaled up and down, etc, so defaulting everything to 1 rather than 0 could cause extra billing as well as app malfunctions. This is why non-web processes are scaled to zero by default.

Isisiskenderun answered 15/11, 2016 at 23:44 Comment(0)
A
6

I just ran into the same problem and worked it around doing this in my Procfile after reading Shibumi's answer:

web: echo "useless"
service: node index.js
Aldose answered 23/10, 2019 at 14:14 Comment(4)
I am trying to deploy docker and am using heroku.yml file instead of Procfile. Any idea what do i do in this case?Higginson
Ha! That's interesting. If going down that path, you could even maybe do something like web: false to just return 1 so that Heroku knows it "failed"; you might even get some feedback in the UI from a non-zero return value.Isisiskenderun
@MatejJ There looks to be some good information here: devcenter.heroku.com/articles/build-docker-images-heroku-ymlIsisiskenderun
Unfortunately this does not stop the web dyno spinning up (and staying on) which I believe is the intention of the questionDeictic
I
0

The actual correct whay to do it is running on your terminal:

heroku scale web=0 worker=1 --app YOUR_APP_NAME_HERE

It will disable web and set one worker

On your Procfile you must keep worker: your-startup-command

Inflationism answered 19/9, 2023 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.