Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 936
Shibumi Avatar asked Oct 26 '16 14:10

Shibumi


People also ask

Can I deploy on Heroku for free?

Heroku offers a free plan to help you learn and get started on the platform. Heroku Buttons and Buildpacks are free, and many Heroku Add-ons also offer a free plan. Experiment easily with different technologies to discover what works best for you and your apps.

How do I start a node app on Heroku Dyno?

To determine how to start your app, Heroku first looks for a Procfile . If no Procfile exists for a Node.js app, we will attempt to start a default web process via the start script in your package.json. The command in a web process type must bind to the port number specified in the PORT environment variable. If it does not, the dyno will not start.

Does Heroku support Node JS?

the Heroku CLI. The details of Heroku’s Node.js Support are described in the Heroku Node.js Support article. Heroku Node.js support will only be applied when the application has a package.json file in the root directory.

How does Heroku determine how to start an app?

To determine how to start your app, Heroku first looks for a Procfile . If no Procfile exists for a Node.js app, we will attempt to start a default web process via the start script in your package.json.

Why is my Dyno not starting on Heroku?

The command in a web process type must bind to the port number specified in the PORT environment variable. If it does not, the dyno will not start. For more information, see Best Practices for Node.js Development and Heroku Node.js Support.


2 Answers

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
like image 185
rulojuka Avatar answered Oct 02 '22 13:10

rulojuka


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.

like image 38
Shibumi Avatar answered Oct 02 '22 12:10

Shibumi