Deploying Node.JS express API App to Azure App Service - node.js

I'm trying to deploy my Node.JS app to Azure App Service. I followed this introduction: https://learn.microsoft.com/de-de/azure/app-service/app-service-web-get-started-nodejs.
Here is the code of my app:
var express = require('express'); // Web Framework
var app = express();
var sql = require('mssql'); // MS Sql Server client
const { request } = require('http');
// Connection string parameters.
var sqlConfig = {
user: 'username',
password: 'password',
server: 'serveraddress',
database: 'databasename'
}
// Start server and listen on http://localhost:80/
var server = app.listen(80, function () {
var host = server.address().address
var port = server.address().port
console.log("app listening at http://%s:%s", host, port)
});
app.get('/tags', function (req, res) {
sql.connect(sqlConfig, function() {
var request = new sql.Request();
request.query('select * from dbo.Tag', function(err, recordset) {
if(err) console.log(err);
res.end(JSON.stringify(recordset)); // Result in JSON format
});
});
})
The app runs locally without any problems. Simple testing in browser by typing localhost:80/tags returns all tags as json.
But after deployment to Azure this error occurs:
2020-06-25T17:11:58.055Z ERROR - Container wearxapplication_0_ed215082 for site wearapplication did not start within expected time limit. Elapsed time = 230.0801107 sec
2020-06-25T17:11:58.074Z ERROR - Container wearxapplication_0_ed215082 didn't respond to HTTP pings on port: 8080, failing site start. See container logs for debugging.
2020-06-25T17:11:58.088Z INFO - Stopping site wearxapplication because it failed during startup.
What its mean? How solve it?

Looking at the errors, I believe you are using App Service on Linux with Single container configuration. If so, do not explicitly listen on port 80 or any other (unless you are deploying via custom container where you would have control of the docker file). Behind the scene, app service on Linux deploys a container and expose an auto-detected port (docker expose). Your explicit listening port is unlikely to match that auto-detected port. Replace you server bootstrap code with below snippet to let the port get picked up from environment:
// Start server and listen on http://localhost:port/ for local
const port = process.env.PORT || 1337; // for local debugging choose any available port
var server = app.listen(port, function () {
var host = server.address().address;
console.log("app listening at http://%s:%s", host, port);
});
One more thing to check is whether any of the dependencies (express, mssql in your case) failed to resolve at startup. This can happen when you have the dependency missing in node_modules folder. You can check that by starting Log Stream (you can find in Azure portal app service blade). You might see error like this
Log stream

Related

APP Engine listening to Port 3000 giving 502 Bad Gateway error

I am new to node.js coding. I am learning to build a app I want to host on GCP App engine.
I have created a Node.js code which has hard requirement to listen to port 3000.
const dotenv = require('dotenv').config();
const express = require('express');
const app = express();
const crypto = require('crypto');
const cookie = require('cookie');
const nonce = require('nonce')();
const querystring = require('querystring');
const request = require('request-promise');
const { Console } = require('console');
// const PORT = process.env.PORT || 3000;
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello App Engine!');
});
On Yaml file I have specifically added ports to forward.
network:
forwarded_ports:
- 3000/tcp
unless I dont use 8080 port, app engine is failing with 502 Bad Gateway.
Is there a way I can use Port 3000 in App engine.
It works if I change the Port to 8080. But I want this to be at 3000.
I created firewall rules
enter image description here
Nope, you cannot change the default port in GAE.
The forwarded_ports is intended to open access to other services listening on other ports but always there should be something listening on the port 8080.
You can create a dummy service listening in port 8080 and possibly redirect to your app in port 3000. Something else to keep in mind is that when accessing the desired service in port 3000 or any other, this should be specified in the url like https://PROJECT_ID.REGION_ID.r.appspot.com:3000 or more general https://PROJECT_ID.REGION_ID.r.appspot.com:PORT

NODEJS,SOCKET on port 8070 connecting on rendering but not directly opening

I have a cpanel where Apache is activated and displaying my website on port 80,443 https://mydomain.io
The below setup works on port 80 but not on other ports like if I want to run this at Port 8070
I want to run nodejs on port 8070 i.e http://IP:8070
SERVER SIDE
server.js
var compression = require('compression');
var _ = require('lodash');
var express = require('express');
var server = express();
var app = require('http').createServer(server);
var io = module.exports.io = require('socket.io')(app);
server.use(compression());
app.get('/', (req, res) => {
res.sendFile(__dirname + '/tester.html');
});
app.listen(8070, function(){
console.log('listening on *:' + 8070);
});
Now when I open this IP:8070 this renders the HTML and it connects to sockets
WORKING
console.log(io.connect());
But I want to access it via mydomain.io
so If I try to go to mydomain.io/tester.html or a file locally on my pc
It doesn't connect to sockets
//NONE OF THESE WORKING!
WITH HTTP GETTING ERR:
console.log(io.connect('http://mydomain.io:8070/', { transports: ["websocket"]}));
console.log(io.connect('http://localhost:8070/', { transports: ["websocket"]}));
console.log(io.connect('http://localhost/', { transports: ["websocket"]}));
console.log(io.connect('http://mydomain.io/', { transports: ["websocket"]}));
console.log(io.connect());
GETTIG ERR: Mixed Content: The page at '<URL>' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws:<URL>/socket.io/?EIO=3&transport=websocket'. This request has been blocked; this endpoint must be available over WSS.
WITH HTTPS NOT WORKING
console.log(io.connect('https://mydomain.io:8070/', { transports: ["websocket"]}));
console.log(io.connect('https://localhost:8070/', { transports: ["websocket"]}));
console.log(io.connect('https://localhost/', { transports: ["websocket"]}));
console.log(io.connect('https://mydomain.io/', { transports: ["websocket"]}));
WITH PORT 80 ITS WORKING BUT NOT ON ELSE
BUT if I run my server.js at port 80 and stopping apache using service httpd stop
then it works with mydomain.io/tester.html or a file locally on my pc
var socket = io.connect('wss://mydomain.io'); //Socket Address WOKRING
Yes, Thank you #v1shva, trying https.createserver instead of http createserver with my cpanel keys and cert file I am able to connect with this from anywhere.
Thank You

Adding GraphQL subscriptions to the existing express app using single server

GraphQL playground subscription fails with 400 error code.
WebSocket connection to 'ws://localhost:3000/graphql' failed: Error during WebSocket handshake: Unexpected response code: 400
I have an existing code based on express. I've integrated Apollo v2 this way:
const { ApolloServer, PubSub, gql } = require('apollo-server-express');
...
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers
});
server.applyMiddleware({ app });
...
app.listen(port, () =>
console.log(chalk.blue(`App listening on port ${port}!`)),
);
and then i start my existing app on port 3000 and can access the GraphQL playground on http://localhost:3000/graphql. All queries and mutations work as expected
Now I want to add subscriptions. Turns out I need to use an http server:
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);
and then listen to it on another port:
httpServer.listen(3005, () => {
console.log(`Server ready at http://localhost:3005${server.graphqlPath}`);
console.log(`Subscriptions ready at ws://localhost:3005${server.subscriptionsPath}`);
});
So I have two servers running. My own on port 3000 and the subscriptions server on 3005. Is that the right way? Is it the only way?
There's no need to call both app.listen and httpServer.listen -- calling httpServer.listen will expose both your Express app and the subscription server.
Additional reading: Express.js - app.listen vs server.listen

How to troubleshoot problem with setting WebRTC server on vps?

I wrote a simple node express server for webRTC using peerjs-server and simple client using peerjs. Everything works fine on localhost, but when I try it on vps, I get error:
Firefox can't connect with server ws://my.vps/peerjs/peerjs?key=peerjs&id=hj3hpekwaa38fr00&token=ymtfvhagiw
PeerJS: Socket closed.
PeerJS: ERROR Error: Lost connection to server.
Error: "Lost connection to server."
emitError https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:16426
_initializeServerConnection https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:12260
emit https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:25516
onclose https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js:1:19350
Server:
const express = require('express');
enter code here`const app = express();
const ExpressPeerServer = require('peer').ExpressPeerServer;
app.use(express.static('./public'));
const server = app.listen(80, () => { // 3000 on localhost
console.log('Express server listen on port ' + 80);
});
const options = { debug: true };
const peerserver = ExpressPeerServer(server, options);
app.use('/peerjs', peerserver);
app.use('/*', express.static('./public/index.html'));
Client:
var peer = new Peer('', {
host: location.hostname,
port: location.port || (location.protocol === 'https:' ? 443 : 80),
path: '/peerjs',
debug: 3
});
peer.on('open', function (id) {
console.log(id);
});
Any help appreciate.
It looks like you are connecting with server ws://my.vps/, which is a web socket to a server at http://my.vps/ which doesn't seem to exist.
It should probably also be using https (or wss)

node.js https server not loading responding

I am trying to start a https node.js server.
I started by creating a certificate and key following this guide:
http://gaboesquivel.com/blog/2014/nodejs-https-and-ssl-certificate-for-development/
and I placed them in my /app_name/security/keys directory.
To start my https server, I have the following:
const https = require('https'),
fs = require('fs');
if(app.get('env') === 'development') {
console.log('dev env!!'); //prints correctly
console.log('port: ' + port); //prints correctly
const options = {
key: fs.readFileSync('./security/keys/key.pem'),
cert: fs.readFileSync('./security/keys/cert.pem')
};
https.createServer(options, (req, res) => {
console.log('https good to go'); //this does not print out anything
}).listen(port);
}
When I go to https://localhost:3000, the page throws an error
This site can’t be reached
localhost unexpectedly closed the connection.
ERR_CONNECTION_CLOSED
But there's no error on the server side console. Furthermore, if i go to the regular localhost:3000, I get:
The localhost page isn’t working
localhost didn’t send any data.
ERR_EMPTY_RESPONSE
Can someone help?
Thanks in advance!
---- UPDATE ----
I'm running on port 443 now. Initially I got an error:
Error: listen EACCES 0.0.0.0:443 so I ran:
sudo NODE_ENV=development nodemon app
Which did not throw any errors. However, when I went to https://localhost:443, I get:
This site can’t be reached
localhost unexpectedly closed the connection.
I used express as a web server.
to install express:
npm install express --save
I took your code, added the usage in express, generated certificate using openssl, and executed it - all looked good, the server was up, listening to port 3000 over https.
My code (which is based on your code...):
var app = require('express')();
const https = require('https'),
fs = require('fs'),
port = 3000;
if(app.get('env') === 'development') {
console.log('dev env!!'); //prints correctly
console.log('port: ' + port); //prints correctly
const options = {
key: fs.readFileSync('/tmp/private.key'),
cert: fs.readFileSync('/tmp/publickey.crt')
};
https.createServer(options, (req, res) => {
console.log('https good to go'); //this does message appears!!! ^_^
}).listen(port);
}
Please pay attention to the way I defined app: var app = require('express')();
You can split this definition into two line if it's more readable:
var express = require('express');
var app = express();
So many problems with your code.
I tested this really quickly.
the keyword app and port is not defined, lines 4 and 7 respectively.
That will throw you a syntax error, preventing the code from continuing any further therefore server not starting up at all.
As I mentioned on my comment, use devtool to debug and use the following line on a CLI devtool server.js -w where the -w watches for file changes and reloads the server on the fly, while developing.
also assuming you named your entry file server.js

Resources