Cannot Connect to Dockerized Express HTTPS Server - node.js

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 :)

Related

Port number showing in Nodejs express folder listing

I have a node js express application which is running on port 3000. when i ran it first it worked. Then when i ran it for the second time, it says the "port is already in use". I have checked all the running ports and also searched by specific 3000 port, but still cannot find a process running on 3000 port.
Then i changed the port to 3002 and checked, now the program ran. And when i closed and ran it again, it says "port is already in use".
Same is the case when i tried with port 3003.
i tried the below to check for the running ports
sudo lsof -i -P -n | grep LISTEN
netstat -an | grep 3000
lsof -i:3000
kill <PID>
Afterwards i noticed that when i did a folder listing it showed the folder "3000", "3002", "3003" as folder/file. I don't know what this is.
below is my www file
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mqtt-node:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3001');
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);
}
Could anyone help me with why the ran port numbers are showing in the folder listing and also i cannot find any running node ports, but still says the port is already in use.
I made a change in my env file and the issue is resolved. I had defined the port in my .env as PORT="3000" and i changed to PORT=3000, and it works.
I am not sure why PORT="3000" was working in my PC and not in my server. This is why i was not focusing on this factor.

Can't connect to NodeJS server from Angular Frontend

I'm working on an Angular app, which connects to postgresql and make a simple operations on it. On Virtual Machine everything works perfectly, but when I started to test it on official server things goes worse.
My Angular Frontend works great, everything shows up etc but when I'm going to login, when I press the button there are this error in console:
zone.js:2969 OPTIONS http://192.168.30.5:3132/auth/login
net::ERR_CONNECTION_TIMED_OUT
My Frontend works on port 4200 and I start it with
ng serve --host=192.168.30.5
NodeJS server starts with just
node server.js
I've checked netstat -nltp and it shows:
192.168.30.5:4200 0.0.0.0:* LISTEN 20597/ng serve --ho
:::3132 :::* LISTEN 20665/node-default
I tried to test other address combinations (Use localhost instead of 192.168.30.5, use 0.0.0.0 instead, use 127.0.0.1 etc) and nothing worked.
One thing that I saw is, when I use address 192.168.30.5, the error is
ERR_CONNECTION_TIMED_OUT
but when I use localhost, error changes to
ERR_CONNECTION_REFUSED
I expect this app to work like on the VM, so when I, fo example, click the login button, it logs me in instead of showing error in console. I would be grateful for any help.
My server.js file:
console.log("NodeJS Activated");
(function () {
'use strict';
const app = require('./app');
const debug = require('debug')('herman-express:server');
const http = require('http');
const port = normalizePort(process.env.PORT || '3132');
app.set('port', port);
const server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
const port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
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;
}
}
function onListening() {
const addr = server.address();
const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
debug('Listening on ' + bind);
}
}());

how to set local node ports for production?

Trying to bring a local project onto an ubuntu mongodb server.
Currently the project runs on my localhost:8000 when I run npm start on my server and I visit curl http://localhost:8000 i can see the markup of my homepage being outputted. How can i change this to use my domain/server ip in production?
Below is my node file which is run by npm start
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('05-express-first-app:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8000');
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);
}
My server ip address is: 165.227.196.209, just not sure where to put it.
Thanks!
You'll have to change the IP on which the Node.js server runs to be whatever the public IP address of your server is. In your case, the public IP is 165.227.196.209
This is assuming your name server is already configured to route the domain (eg: mywebsite.com) to that particular IP address.
Read more about it here - How to assign a domain name to node.js server? (Check the selected answer)
UPDATE:: Opening the URL - http://165.227.196.209/,
I notice that you're using nginx. So you'll have to setup reverse proxying.
I suggest going through the link here - Node.js + Nginx - What now?
You can read about the benefits of putting nginx infornt of Node.js here - Using Node.js only vs. using Node.js with Apache/Nginx
Couple of other problems that I notice here that would be good to fix,
You should be using a process manager to run your application in Production. Something like pm2 is recommended. This way if you application crashes, pm2 will restart it.
You can use pm2 with environment variables as described here to run on a different port on production - http://pm2.keymetrics.io/docs/usage/environment/

Certbot - How to create SSL certs and keys for IP:3030?

I have an ExpressJS app that is running on an IP address only at port 3030.
How can I create the SSL cert and key for this type of address?
I tried with:
$ certbot certonly --standalone --email test1#yahoo.co.uk -d 127.0.1.1:3030
I get this error:
Requested domain 127.0.1.1:3030 is not a FQDN
Any ideas?
This is the package I use - certbot.
This is my www file in my ExpressJS bin directory:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mongoose-iot:server');
var http = require('http');
// Add HTTPS support.
// https://www.hacksparrow.com/express-js-https.html
// http://stackoverflow.com/questions/11744975/enabling-https-on-express-js
// http://blog.mgechev.com/2014/02/19/create-https-tls-ssl-application-with-express-nodejs/
var https = require('https');
var fs = require('fs');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
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);
/**
* Get port from environment and store in Express.
*/
var httpsPort = normalizePort(process.env.PORT || '3030');
app.set('port', httpsPort);
/**
* Create HTTPS server.
*/
var options = {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem')
};
var httpsServer = https.createServer(options, app);
/**
* Listen on provided port, on all network interfaces.
*/
httpsServer.listen(httpsPort);
httpsServer.on('error', onError);
httpsServer.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);
}
The problem is that letsencrypt ssl certficates are for domain names, it doesn't have much to do with the IP address or the port. You must have a valid and publicly accessible domain name so that the letsencrypt authority server can verify it.
In this case it is common practice to use http (and not https) in development using a simple check like:
if (process.env.NODE_ENV === "production") {
// httpsServer.listen(httpsPort)
} else {
// ...
}

NodeJS app not working on Openshift after deployed

I'm having trouble with my nodejs app deployment. I use Express, MySQL and the basic Express structure for my app. When I open the app URL on openshift I get the 503 error message. On the nodejs.log, I can see this:
Warning: connect.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and will not scale past a single process.
Pipe 8080 is already in use
The application is run with ./bin/www. This is the code I have in that file:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('adressbook:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
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 addr = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
The error occurred because the OPENSHIFT_NODEJS_PORT variable was not set on your application's server. This cause the application to use the hardcoded port (8080).
To resolve this, you need to set the OPENSHIFT_NODEJS_PORT environment variable on your application's server. This can be done with:
$ rhc env set OPENSHIFT_NODEJS_PORT=<Value> -a App_Name
where <Value> is the port number you wish to use and App_Name is your application's name.
You can read more about handling environment variables on Openshift here

Resources