You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Heroku上获取非Web进程端口?含HapiJS代理场景

嘿!咱们一步步来解决你的两个问题:

1. 如何在Heroku上查询Web进程之外其他进程使用的端口
  • 通过环境变量查询:如果你的非Web进程(比如worker或者自定义dyno)是用环境变量来指定端口的(比如WORKER_PORT),直接用Heroku CLI就能获取这个值:
    heroku config:get WORKER_PORT
    
    不管你是通过heroku config:set WORKER_PORT=XXXX命令设置的变量,还是在Procfile/代码里定义的,这个方法都管用。
  • 查看dyno日志:如果你的进程启动时会打印监听的端口信息,你可以过滤对应dyno的日志来查看:
    heroku logs --dyno=<你的dyno名称>
    
    把<你的dyno名称>换成你的非Web进程dyno的名字(比如Procfile里定义的worker),然后找包含“listening on port”或者类似描述的日志行就行。
  • 直接在dyno里执行命令:用Heroku的exec功能进入运行中的dyno shell,然后用网络工具查看开放端口:
    1. 先进入dyno shell:
      heroku ps:exec --dyno=<你的dyno名称>
      
    2. 进入后,用ss命令(Heroku dyno里一般没有netstat,ss更常用)列出监听的端口:
      ss -tulpn
      
      这个命令会显示所有正在监听端口的进程,你可以通过进程名称找到对应的非Web进程端口。
2. 在HapiJS中获取非Web进程的端口并代理请求

首先要明确:Heroku不会像给Web进程自动分配$PORT环境变量那样,给非Web dyno自动分配端口。所以你需要给私有Webhook服务器显式设置一个端口变量,然后在HapiJS应用里读取它。下面是完整的实现步骤:

步骤1:配置Webhook服务器使用环境变量端口

修改你的Webhook服务器代码,从环境变量读取端口(不要硬编码),示例:

// webhook-server.js
const port = process.env.WEBHOOK_PORT || 3001; // 本地开发时 fallback 到3001
// ... 启动服务器并监听 port 端口

然后在Heroku上设置这个环境变量:

heroku config:set WEBHOOK_PORT=3001

如果你的HapiJS服务器和Webhook服务器运行在同一个dyno里(比如Procfile里用web: node server.js & node webhook-server.js这样的命令启动),这个环境变量会被两个进程共享。

步骤2:在HapiJS中配置代理

使用Hapi官方的代理插件@hapi/h2o2来将特定请求转发到私有Webhook服务器,设置方法如下:

  1. 安装插件:
    npm install @hapi/h2o2
    
  2. 在HapiJS服务器中注册插件并添加代理路由:
    // server.js
    const Hapi = require('@hapi/hapi');
    const h2o2 = require('@hapi/h2o2');
    
    const init = async () => {
      const server = Hapi.server({
        port: process.env.PORT || 3000,
        host: '0.0.0.0'
      });
    
      // 注册代理插件
      await server.register(h2o2);
    
      // 添加代理路由,将/webhook下的所有请求转发到Webhook服务器
      server.route({
        method: ['GET', 'POST', 'PUT'], // 匹配Webhook支持的HTTP方法
        path: '/webhook/{path*}', // 代理/webhook下的所有路径
        handler: {
          proxy: {
            uri: `http://localhost:${process.env.WEBHOOK_PORT}/{path}`,
            passThrough: true, // 转发请求头、请求体等信息
            xforward: true // 设置X-Forwarded-For、X-Forwarded-Proto等头部
          }
        }
      });
    
      await server.start();
      console.log('服务器运行在 %s', server.info.uri);
    };
    
    init();
    

这样一来,所有发送到你的Heroku应用域名/webhook/...的请求,都会被转发到运行在localhost:<WEBHOOK_PORT>/...的私有Webhook服务器。

重要注意事项

  • 如果你的Webhook服务器和HapiJS服务器在不同的dyno里,localhost就无法访问了。这种情况下你需要用Heroku私有空间或者其他私有网络方案,不过复杂度会高很多。大部分场景下,把两个进程放在同一个dyno里做内部代理是更简单的选择。
  • 永远用环境变量而不是硬编码端口——这样你的应用在本地开发和Heroku部署时都能灵活适配。

内容的提问来源于stack exchange,提问作者bobber205

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:32:56