Angular/Node Express+Flask API部署Heroku:API无法正常连接
我来帮你解决这个Heroku部署的问题,你的核心问题是前后端在Heroku的不同dyno容器里无法互相访问,再加上配置上的几个小疏漏,下面给你两种可行的解决方案:
方案1:将Flask后端部署为独立的Heroku Web服务(推荐)
这种方式让前后端各自独立运行,更符合微服务架构,也方便后续单独扩容维护。
步骤1:修正Flask后端代码
Heroku会给每个服务分配动态端口,而且容器内需要监听所有地址才能被外部访问,修改你的runner.py:
import os from flask import Flask, request, jsonify, json, render_template from flask_cors import CORS app = Flask(__name__) CORS(app) # Runs the application if __name__ == "__main__": # 读取Heroku分配的PORT环境变量,本地默认用5000 port = int(os.environ.get('PORT', 5000)) # 监听0.0.0.0,允许容器外部访问 app.run(host='0.0.0.0', port=port, debug=False) # 生产环境记得关闭debug
步骤2:为Flask后端创建独立Heroku应用
- 把Flask代码单独放在一个目录,初始化git仓库
- 创建Heroku应用:
heroku create your-flask-api-app(替换成你自己的应用名) - 在这个目录下创建
Procfile,内容为:web: python runner.py - 把Flask代码部署到这个新的Heroku应用
步骤3:修改前端API请求地址
Angular的proxy.conf.json只在本地ng serve时生效,部署到Heroku后需要直接指定后端的真实地址:
- 在
src/environments/environment.prod.ts中添加API地址配置:
export const environment = { production: true, apiUrl: 'https://your-flask-api-app.herokuapp.com/api' };
- 把你代码中所有请求
/api的地方,替换成environment.apiUrl
步骤4:重新部署前端到Heroku
这样前端在Heroku上就能直接请求独立的Flask API服务,彻底解决跨容器访问的问题。
方案2:将前后端部署在同一个Heroku Dyno中
如果不想分开部署,可以用进程管理器让前后端在同一个容器里同时运行。
步骤1:安装进程管理器
在前端项目目录下安装pm2(用于同时管理Node和Flask进程):
npm install pm2 --save
步骤2:创建pm2配置文件
在项目根目录新建ecosystem.config.js:
module.exports = { apps : [{ name: 'frontend', script: 'server.js', env: { PORT: process.env.PORT || 8080 } }, { name: 'backend', script: 'python runner.py', env: { BACKEND_PORT: process.env.BACKEND_PORT || 5000 } }] };
步骤3:修改Procfile
把原来的两个dyno配置替换成:
web: pm2-runtime ecosystem.config.js
步骤4:给Node添加反向代理
因为前后端在同一个容器里,我们可以让Node把/api请求转发到Flask后端:
首先安装代理依赖:
npm install http-proxy-middleware --save
然后修改server.js:
const express = require('express'); const path = require('path'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); // 反向代理API请求到Flask后端 app.use('/api', createProxyMiddleware({ target: 'http://localhost:5000', changeOrigin: true })); app.use(express.static(__dirname + '/dist/client')); app.get('/*', function(req,res) { res.sendFile(path.join(__dirname+'/dist/client/index.html')); }); app.listen(process.env.PORT || 8080);
步骤5:修正Flask端口配置
修改runner.py,确保监听正确的后端端口:
import os from flask import Flask, request, jsonify, json, render_template from flask_cors import CORS app = Flask(__name__) CORS(app) if __name__ == "__main__": port = int(os.environ.get('BACKEND_PORT', 5000)) app.run(host='0.0.0.0', port=port, debug=False)
步骤6:重新部署到Heroku
这样前后端就会在同一个dyno里运行,前端通过Node的反向代理访问后端,避免跨容器的问题。
为什么你的原有配置不工作?
- Heroku的非
web类型dyno(比如你用的server)默认不对外暴露端口,只有webdyno能接收外部HTTP请求; - 前端在Heroku上仍请求
localhost:5000,但这个地址只在前端自己的容器内有效,无法访问到后端的serverdyno; - Flask后端默认监听
127.0.0.1,即使端口正确,也无法在容器外部被访问。
内容的提问来源于stack exchange,提问作者ihatecodinglmao




