我目前正在尝试将应用部署到单个Heroku dyno,它不使用create-react-app但是有一个用于webpack的快速服务器和一个rails API后端。
我遇到快速代理我的API请求的问题(但在本地工作正常),这是Heroku日志的错误:
2017-12-03T16:00:18.436271+00:00 app[web.1]: Error: connect ECONNREFUSED 127.0.0.1:3005
2017-12-03T16:00:18.436308+00:00 app[web.1]: at Object.exports._errnoException (util.js:1018:11)
2017-12-03T16:00:18.436309+00:00 app[web.1]: at exports._exceptionWithHostPort (util.js:1041:20)
2017-12-03T16:00:18.436311+00:00 app[web.1]: at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
我确保将节点和轨道的buildpack用作described here。
以下是相关代码:
Procfile
web: npm run start:prod
api: bundle exec rails server --port=3005 --environment=production -b 127.0.0.1
的package.json
{
"name": "foo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"proxy": "http://127.0.0.1:3005/",
"engines": {
"node": "6.10.2",
"yarn": "0.24.5",
"npm": "5.5.1"
},
"scripts": {
"start": "NODE_ENV=development node server",
"start:prod": "yarn run build && NODE_ENV=production node server",
"build": "NODE_ENV=production webpack -p --config ./webpack.prod.js --progress --colors --display-error-details"
},
server.js
const express = require('express');
const proxy = require('express-http-proxy');
const app = express();
const port = process.env.PORT || 3000;
const path = require('path')
const webpack = require('webpack')
const proxyHost = '127.0.0.1';
const proxyPort = '3005';
app.use('/api', proxy(`${proxyHost}:${proxyPort}`));
const isProd = process.env.NODE_ENV === 'production'
let config
if (isProd) {
config = require('./webpack.prod.js')
} else {
config = require('./webpack.dev.js')
}
const publicPath = config.output.publicPath || '/';
const outputPath = config.output.path || path.resolve(process.cwd(), 'dist');
if (!isProd) {
console.log('Development env detected: Initializing hot reloading')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddleware = require('webpack-hot-middleware')
const compiler = webpack(config)
app.use(webpackHotMiddleware(compiler, {
log: console.log,
path: '/__webpack_hmr'
}))
app.use(webpackDevMiddleware(compiler, {
entry: config.entry,
publicPath: config.output.publicPath,
stats: {
colors: true
}
}))
app.use('*', function (req, res, next) {
const filename = path.join(compiler.outputPath, 'index.html')
compiler.outputFileSystem.readFile(filename, (err, result) => {
if (err) {
return next(err)
}
res.set('content-type', 'text/html')
res.send(result)
res.end()
})
})
} else {
app.use(publicPath, express.static(outputPath));
app.get('*', (req, res) => res.sendFile(path.resolve(outputPath, 'index.html')));
}
app.listen(port, (err) => {
if (err) {
console.log(err.message)
} else {
console.log(`Server Started at port ${port}`);
}
});
非常感谢任何帮助!
编辑解决方案
所以我能够根据下面接受的答案找到解决方案,但我想我会更新帖子以详细说明。
正如答案所指出的,似乎Heroku在你的Procfile中每个进程使用不同的dyno,这就是为什么前端/后端服务器最初无法相互通信的原因。
为了避免这种情况,我只是创建了一个虚拟的proc文件,它使用foreman来初始化真正的proc文件:
Procfile(Heroku使用的假人)
web: foreman start -f StartProcfile
StartProcfile(实际流程)
web: npm run start:prod
api: bundle exec rails server --port=3005 --environment=production
应该注意的是,在我的情况下,我遇到了超出dyno内存上限的额外问题,并且花费超过60秒来绑定到指定的heroku端口。事实证明这是因为我将构建步骤作为web
进程的一部分,当我应该使用postinstall
中的package.json
挂钩时。
的package.json
"scripts": {
"start": "NODE_ENV=development node server",
"start:prod": "NODE_ENV=production node server --optimize_for_size --max_old_space_size=460 --gc_interval=100",
"build": "NODE_ENV=production webpack -p --config ./webpack.prod.js --progress --colors --display-error-details",
"postinstall": "npm run build"
},
答案 0 :(得分:1)
Procfile
中的每一行最终都会在一个单独的dyno中运行。如果您需要在同一个dyno上运行这两个进程(在本例中为web
),那么您需要重新定义web
以调用启动节点服务器的shell脚本,然后启动rails服务器,或让节点启动过程启动rails服务器。
完全披露,我从未真正做过你正在尝试的事情。即使在进行上述更改后,将rails API服务器绑定到端口3005也可能无法正常工作。但是,毫无疑问,127.0.0.1
进程中的web
永远不会在127.0.0.1
进程中api
,因为它们将始终在不同的dynos上运行。希望这些信息有所帮助。