是否可以在没有 Web dyno 的情况下将 Node.js 应用程序部署到 Heroku?
Posted
技术标签:
【中文标题】是否可以在没有 Web dyno 的情况下将 Node.js 应用程序部署到 Heroku?【英文标题】:Is it possible to deploy a Node.js application to Heroku without a web dyno? 【发布时间】:2017-03-09 00:31:13 【问题描述】:对于一些背景故事和参考,这里是一些 Heroku 文档页面的引用。
来自Heroku Node.js Support > Activation:
当应用程序在根目录中有
package.json
文件时,将使用 Heroku Node.js 构建包。
来自Heroku Node.js Support > Default web process type:
首先,Heroku 查找指定进程类型的 Procfile。
如果在构建过程中您的应用的根目录中不存在
Procfile
,您的Web 进程将通过运行npm start
来启动,[...]
来自Process Types and the Procfile > Process types as templates:
Procfile 包含许多进程类型声明,每个声明都在一个新行上。每个进程类型都是在启动该进程类型的测功机时执行的命令的声明。
例如,如果声明了
web
进程类型,则当启动此类型的测功机时,将执行与web
进程类型关联的命令。例如,这可能意味着启动 Web 服务器。
我在根目录中有一个package.json
文件(这将激活 Node.js 构建包),我还在根目录中包含了一个Procfile
,其内容如下:
service: npm start
我假设不定义 web
dyno 会导致它无法创建;按照Procfile
中声明的配置,只应创建service
dyno。
相反,发生的事情是使用npm start
自动创建了一个活动 web
dyno 和一个非活动 service
dyno是使用Procfile
中的定义创建的。然后我不得不:
heroku ps:scale web=0
heroku ps:scale service=1
我绝对可以想象想在 Heroku 上运行一个不接受任何传入连接,只进行传出连接的 Node.js“服务”应用程序。有没有办法将 Node.js 构建包配置为在未定义时不自动创建web
dyno?我浏览了很多文档,寻找一种方法:(1) 将其定义为这样或 (2) 自动删除生成web
dyno;但是,我什么都没找到。
感谢您的帮助!
【问题讨论】:
【参考方案1】:我最终在 Heroku 上开了一张帮助台票。得到了他们的回复,所以我会在这里发布。感谢 Heroku 支持!
简短的回答是,不,目前您需要heroku scale web=0 service=1
才能在没有公共web
进程的情况下运行服务。更详细的解释:
在早期,Node.js Buildpack 会检查是否存在 Procfile
,如果缺少,则会使用 web: npm start
创建一个默认值。这使得在没有 Web 进程的情况下创建应用程序变得容易,因为您可以只提供定义一些进程的 Procfile
,从列表中省略 web
。
但是,随着越来越多的用户需要构建包数组而不是单个构建包,该解决方案产生了问题。 Node 是最受欢迎的第一个 buildpack,因为 Java、Python、php 和 Ruby 应用程序经常使用它来构建前端资产。每当一个没有Procfile
的应用首先运行Node,然后再运行另一个buildpack,Node 就会注入它自己的默认Procfile
(web: npm start
),然后第二个buildpack 不会创建它的默认Procfile
,因为它已经存在于文件系统。因此,当应用程序中缺少一个 Procfile 时,注入一个默认的 Procfile 会给多语言应用程序的下游带来问题。
所以,我们stopped creating a default Procfile and instead used default_process_types in bin/release。这解决了后续 buildpacks 继承不正确的默认 Procfiles 的问题,但由于 default_process_types
被Procfile
进程列表扩展 而不是替换,因此没有web
的应用程序在他们的Procfile
中定义的进程将合并默认的web
进程。这就是为什么web
即使在Procfile
中没有web
条目也会出现。
我们也不想让任何客户感到意外的账单。一些应用程序有许多进程类型,其中一些只是偶尔运行,一些仅限于单个实例,一些需要按比例放大和缩小等,因此将所有内容默认为 1 而不是 0 也可能导致额外的计费作为应用程序故障。这就是为什么非 Web 进程默认缩放为零的原因。
【讨论】:
【参考方案2】:在阅读了 Shibumi 的回答后,我刚刚遇到了同样的问题并在我的 Procfile 中解决了这个问题:
web: echo "useless"
service: node index.js
【讨论】:
我正在尝试部署 docker 并使用heroku.yml
文件而不是 Procfile。知道在这种情况下我该怎么做吗?
哈!那很有意思。如果沿着这条路走下去,你甚至可以做类似web: false
的事情来返回1
,这样Heroku 就知道它“失败”了;您甚至可能会从非零返回值中获得一些 UI 反馈。
@MatejJ 这里似乎有一些不错的信息:devcenter.heroku.com/articles/build-docker-images-heroku-yml以上是关于是否可以在没有 Web dyno 的情况下将 Node.js 应用程序部署到 Heroku?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在没有 PHAsset 的情况下将照片存储在 iPhone 上?
是否可以在没有额外标记或样式父容器的情况下将内联元素水平居中?
javascript:在没有php的情况下将数据存储在文件或数据库中?
是否可以在没有UINavigationController的情况下将UIToolbar放在UICollectionView下面?