Unable to connect error - Node Express app on Linux server - node.js

I receive an 'Unable to Connect' error in my browser when trying to connect to my Node Express application. At (my servers ip address) 1.1.1.1:5000. The application works fine in my development environment but not on my AWS EC2 Linux server.
The Node Express app works on my computer in dev
Port 5000 is allowing incoming TCP. I tested and confirmed this with a smaller application (https://hackernoon.com/deploying-a-node-app-on-amazon-ec2-d2fb9a6757eb).
I confirmed my Node Express application is running . (I am using pm2)
PM2 keeps restarting my Node Express app at ~14s
I tried to curl from my machine to hit port 5000, I received a connection refused error curl: (7) Failed to connect to 1.1.1.1 port 5000: Connection refused
UPDATE
Instead of starting the application with pm2 start app.js I started it with npm start and I the app is hosted at port 5000 successfully.
I can go to 1.1.1.1:5000 and am returned API is running
I use js fetch api to call the backend at 127.0.0.1:5000 and receive a Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:5000/pickTicket/21780482. (Reason: CORS request did not succeed).
2
TypeError: NetworkError when attempting to fetch resource. (*Note: My api is on the same server as my nginx/react app)`
My application starts with app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var compression = require('compression');
var fetch = require('node-fetch');
var pickTicketRouter = require('./routes/pickTicket');
var kdlRouter = require('./routes/kdl')
console.log('Creating API')
var app = express();
app.use(cors());
app.options('*', cors());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(compression());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('API is running\n');
});
app.use('/pickTicket', pickTicketRouter);
app.use('/kdl', kdlRouter)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
/bin/www
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('api:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '5000');
console.log('Listening on port: ', port);
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
package.json
{
"name": "api",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"dev": "nodemon ./bin/www"
},
"dependencies": {
"compression": "^1.7.4",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"express": "~4.16.1",
"forever": "^1.0.0",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"morgan": "~1.9.1",
"mssql": "^5.1.0",
"node-fetch": "^2.6.0",
"sequelize": "^5.11.0",
"tedious": "^6.2.0"
},
"devDependencies": {
"nodemon": "^1.19.1"
}
}
I expect to see get a response from the api but instead got a CORS error.

I have a few questions regarding the different environments. Is your DEV environment hosted in AWS? If not, I would look at AWS Security Groups to make sure to have the correct TCP protocol for your application.
Also, did you deploy this EC2 into the default VPC or did you create your own VPC?
If you have created a VPC, it could be a routing issue or network level issue.

I was calling pm2 start on app.js instead of bin/www

Related

Cannot Connect to Dockerized Express HTTPS Server

I'm trying to serve my app over HTTPS so that I can use a service worker with my React app.
To do this, I added https.createServer() to my Express startup script
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('robotapp:server');
var http = require('http');
var fs = require('fs');
var https = require('https');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8000');
app.set('port', port);
console.log('Listening on localhost:', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Add HTTPS server
*/
if (process.env.NODE_ENV === 'prod') {
https
.createServer(
{
key: fs.readFileSync('sslcerts/server.key', 'utf8'),
cert: fs.readFileSync('sslcerts/server.pem', 'utf8')
},
app
)
.listen(443, function() {
console.log('HTTPS listening on PORT 443');
});
}
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
debug('Listening on ' + bind);
}
When I build the Docker container and start the app, both the HTTP and HTTPS server start up (I can see the "Listening on localhost:8000" and "HTTPS listening on PORT 443" messages). I can successfully access the HTTP version of my app on PORT 8000, but when I go to access PORT 443 on my server I get a "This site cannot be reached" error.
At first I thought maybe I mapped my container ports wrong, but I checked and nothing seems out of ordinary
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16d0013eec8a robotapp:2.1 "npm start" 4 seconds ago Up 3 seconds 0.0.0.0:443->443/tcp, 0.0.0.0:8000->8000/tcp silly_tesla
If anyone has any suggestions as to what I'm doing wrong, please let me know :)

Express app with MSSQL created with CLI not connecting correctly to database

I have a problem with an app I created using the Express CLI. It's important to note that I'm using mssql for my connection to the database.
When I use npm start, the app starts without a problem, but when I run node ./bin/www, the app starts, but it fails to connect to the database. I'm getting the error "Invalid server: undefined".
When I check my package.json file, I have:
"scripts": {
"start": "node ./bin/www",
"debug": "set DEBUG=myapp:* & npm start",
"nodemon": "npx nodemon"
},
As far as I understand, it should be exactly the same to run npm start than node ./bin/www, but for some reason it is not.
As to why this is a problem, I want to leave the app running using pm2, and so, I need to be able to run the app from a file, and not from a command.
This is my www file:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mtloops-web-api:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort('3543');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
This is my database connection file:
const sql = require('mssql')
// const path = require('path')
require('dotenv').config()
var config = {
user: process.env.DBUSERNAME,
password: process.env.DBPASSWORD,
server: process.env.HOST,
database: process.env.DATABASE,
connectionTimeout: 300000,
requestTimeout: 300000,
pool: {
idleTimeoutMillis: 300000,
max: 100
},
options: {
encrypt: false
}
}
async function sp (procedure, params) {
const toReturn = await new sql.ConnectionPool(config).connect().then(pool => {
const request = pool.request()
Object.keys(params).forEach(key => {
if (isNaN(params[key])) {
request.input(key, sql.VarChar(8), params[key])
} else {
var numeric = parseInt(params[key])
request.input(key, sql.Int, numeric <= 0 ? -1 : numeric)
}
})
return request.execute(procedure)
}).catch(error => {
throw error.message
})
return toReturn
}
module.exports = {
sp
}

after page refresh error "No default engine was specified and no extension was provided" in React js

I installed a Reactjs web application, after connected to the port and MongoDB through bin/www and app.js the navigation is not working, when I click on about page it is in the same home page, if I refresh the page I get the following error:
No default engine was specified and no extension was provided
Below is my package.json:
{
"name": "nexg",
"version": "0.1.0",
"private": true,
"dependencies": {
"express": "^4.16.4",
"morgan": "^1.9.1",
"nodemailer": "^4.6.8",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-router-dom": "^4.3.1",
"react-scripts": "2.0.5"
},
"scripts": {
"start": "node ./bin/www",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
This is my app.js code:
const express = require('express');
var path = require('path');
const bodyParser = require('body-parser');
//const nodemailer = require('nodemailer');
var logger = require('morgan');
const app = express();
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost/nexgweb_tech', { promiseLibrary:
require('bluebird') })
//.connect('mongodb://localhost/mern-crud', { useMongoClient: true,
promiseLibrary: require('bluebird') })
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended' :' false' }));
app.use(express.static(path.join(__dirname, 'build')));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Below is the ./src/App.js code:
import React, { Component } from 'react';
import logo from './logo.svg';
import {BrowserRouter, Route, Switch, Link} from 'react-router-dom';
import Home from "./components/Home";
import About from "./components/About";
import Contact from "./components/Contact";
import Services from "./components/Services";
import Navigation from "./components/Navigation";
import './App.css';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Navigation/>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/About" component={About} />
<Route exact path="/Contact" component={Contact} />
<Route exact path="/Services" component={Services} />
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
This is my ./bin/www code:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mean-app:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3005');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
After npm run build build folder with some files are generated, after that, I run the command npm start. The application is running in port but after clicking on another page and clicked on refresh I get the error.
When I change the start in package.json from script start to react scripts start, the navigation works perfectly, even after refresh also no error, but I need to start port and MongoDB before starting the app. That's why I created ./app.js and ./bin/www. The app is not working the above issues have come.
Thanks in advance
This error usually happens when a server's request (Express server) doesn't know how to render the response. Express, in this line, needs to know the extension of the file, or the default view to render the correct response.
With React (in a SPA), you don't need to set a default view engine because it will always render your index.html (which contains your React app), no matter what url you use, and since you are using React Router, the routing is always handled by index.html, and then the router can render the correct route. So what you need to do is to respond with the correct file and extension.
In your ./bin/www try adding this:
app.get('*', (req,res) => {
res.sendFile( 'YOUR INDEX.HTML PATH FILE HERE' );
});
After this line:
app.listen(port);
You have to change 'YOUR INDEX.HTML PATH FILE HERE' for whatever the path for your index.html file is.
If index.html is found here:
__dirname + '/build/index.html'
Then you can set it like this:
app.get('*', (req,res) => {
res.sendFile(path.join(__dirname + '/build/index.html'));
});
If it doesn't work, you can try to add it before:
app.listen(port);
connect-history-api-fallback
You can use the connect-history-api-fallback middleware to always fallback to index.html. This can be used in both dev and prod environments.
Use it like this:
const connectHistoryApiFallback = require('connect-history-api-fallback');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended' :' false' }));
app.use(connectHistoryApiFallback({
verbose: false
}));
// static files and folders must be set after connectHistoryApiFallback
app.use(express.static(path.join(__dirname, 'build')));
app.listen(app.get('port'), (err) => {
console.info('Node app is running on port', app.get('port'));
});

Error Deploying node js app to AWS Elastic Beanstalk

I deployed node js application to AWS EBS. When I run the app, i get the error " 502 Bad Gateway " nginx/1.6.2 . This is what i found out in the log.
env.elasticbeanstalk.com/"
2015/04/21 10:52:01 [error] 3807#0: *86 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.4.86, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8081/", host: "clinicaltrials-env.elasticbeanstalk.com"
This is my package.json file
{
"name": "Clinical_Trial_Analytics",
"version": "1.3.2",
"private": true,
"scripts": {
"start": "node main.js"
},
"dependencies": {
"express": "3.0.6",
"stylus": "0.31.0",
"jade": "0.27.7",
"mongodb": "1.2.7",
"moment" : "1.7.2",
"emailjs": "0.3.3",
"json2html": "1.0.0"
},
"engines": {
"node": "0.12.0",
"npm": "1.1.65"
}
}
This is my main.js file
var express = require('express');
var http = require('http');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/server/views');
app.set('view engine', 'jade');
app.locals.pretty = true;
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'super-duper-secret-secret' }));
app.use(express.methodOverride());
app.use(require('stylus').middleware({ src: __dirname + '/client' }));
app.use(express.static(__dirname + '/client'));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
require('./server/router')(app);
http.createServer(app).listen(app.get('port'), function(){
console.log("Clinical Trials server listening on port " + app.get('port'));
})
I am unable to figure out the issue. Is it with the node version or any other problem? Thanks in advance.
It's important to add the Node command at Configuration Modify software section of your beanstalk app, I can see in your app you are using the command start, so use it as node command, "npm start" that will start your app correctly, this also happens when use the folder and file bin/www to start the Nodejs server.

nodeJS : throw new Error('Can\'t set headers after they are sent.');

This is common SO question but didn't get the solution. So I am again putting it here.
Here is app.js
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
require('./routes/sockets.js').initialize(server);
here is sockets.js inside routes folder
var io = require('socket.io');
exports.initialize = function(server) {console.log('init called');
io = io.listen(server);console.log('io');
io.sockets.on("connection", function(socket){console.log("connected");
socket.send(JSON.stringify({type:'serverMessage',message: 'Welcome to the most interesting chat room on earth!'}));
socket.on('message', function(message){
message= JSON.parse(message);
if(message.type == "userMessage")
{
socket.broadcast.send(JSON.stringify(message));
message.type = "myMessage";
socket.send(JSON.stringify(message));
}
});
});
};
Inside sockets.js console.log('init called'); console.log('io'); is printing well. When i run this app using npm start is got following error:
npm WARN package.json application-name#0.0.1 No repository field.
npm WARN package.json application-name#0.0.1 No readme data.
> application-name#0.0.1 start D:\Applications\New folder\node\chat
> node app.js
init called
info - socket.io started
io
Express server listening on port 3000
GET / 200 312ms - 511
http.js:707
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:707:11)
at ServerResponse.res.setHeader (D:\Applications\New folder\node\chat\node_m
odules\express\node_modules\connect\lib\patch.js:59:22)
at next (D:\Applications\New folder\node\chat\node_modules\express\node_modu
les\connect\lib\proto.js:153:13)
at Function.app.handle (D:\Applications\New folder\node\chat\node_modules\ex
press\node_modules\connect\lib\proto.js:198:3)
at Server.app (D:\Applications\New folder\node\chat\node_modules\express\nod
e_modules\connect\lib\connect.js:66:31)
at Manager.handleRequest (D:\Applications\New folder\node\chat\node_modules\
socket.io\lib\manager.js:564:28)
at Server.<anonymous> (D:\Applications\New folder\node\chat\node_modules\soc
ket.io\lib\manager.js:118:10)
at Server.EventEmitter.emit (events.js:117:20)
at HTTPParser.parser.onIncoming (http.js:2051:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:122:23
)
When i access localhost:3000 in browser all it happens. I am using node version v0.10.10, express 3.4.4.
Got the solution!! It was because of some version mismatch. Here is the dependency that i used
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.4.4",
"socket.io": "0.9",
"jade": "*"
}
}

Resources