You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用PM2启动Node.js生产环境时Docker端口未绑定问题

解决Docker+PM2生产环境端口无法绑定的问题

从你的描述和提供的配置来看,主要有两个关键点导致端口无法绑定,下面逐一分析并给出解决方案:

1. Docker启动命令错误导致端口未映射

观察你的docker ps输出,Node.js容器的名称是nodeapiboilerplate_provision_run_1,这个命名格式说明你是用docker-compose run provision命令启动的生产服务。而**docker-compose run默认不会应用服务定义中的端口映射规则**,这就是为什么容器的PORTS列是空的(对比MongoDB容器的端口映射)。

解决方案:

  • 使用docker-compose up命令启动服务,这会严格按照docker-compose.yml中的配置创建端口映射:
    docker-compose up -d provision
    
    -d参数让容器在后台运行)
  • 如果必须使用docker-compose run,需要加上--service-ports参数来启用端口映射:
    docker-compose run --service-ports provision
    

2. PM2 Cluster模式在Docker容器中的适配问题

你的PM2配置使用了cluster模式,虽然这个模式在宿主机上可以利用多核CPU,但在Docker容器中意义不大——Docker本身提供了容器级别的水平扩展(比如docker-compose up --scale provision=3来启动3个服务实例),容器内单进程更符合Docker的设计理念。另外,Cluster模式下如果进程监听逻辑有问题,也可能导致端口无法正常对外暴露。

解决方案:

修改process.json,将执行模式改为fork,并设置实例数为1:

{
  "apps" : [{
    "name" : "node-api-boilerplate",
    "script" : "./src/server.js",
    "exec_mode" : "fork",
    "exec_interpreter": "babel-node",
    "instances" : 1,
    "merge_logs" : true
  }]
}

同时,建议在server.js中显式指定监听地址为0.0.0.0(虽然Express默认监听0.0.0.0,但显式声明可以避免潜在的环境差异问题):

app.listen(PORT, '0.0.0.0', () => {
  logger.info(`Listening on port ${PORT} (bound to 0.0.0.0)`);
});

验证步骤

修改配置后,按以下步骤验证:

  1. 重启生产容器:docker-compose down && docker-compose up -d provision
  2. 再次运行docker ps,确认Node.js容器的PORTS列显示0.0.0.0:3000->3000/tcp
  3. 查看容器日志确认服务启动:docker logs prod_node_api,应该能看到"Listening on port 3000"的日志
  4. 测试API是否可访问:比如用curl http://localhost:3000/api/v1(根据你的路由调整)

内容的提问来源于stack exchange,提问作者André Andrade

火山引擎 最新活动