node.js do not work after deploy on Heroku - node.js

I am new to node.js and Heroku, I just have deployed for the first time a node.js app to Heroku and when I ran in Heroku, the application did not run so I used the command heroku logs --tail but I had this error:
enter image description here
For idea, my node.js works very fine without Heroku but stop working after deploying it there
Here my index.js:
const express = require("express");
var md5 = require('md5');
var reverseMd5 = require('reverse-md5');
const app = express();
const userRouter = require("./API/users/user.router");
const operationsRouter = require("./API/operations/operations.router");
app.use(express.json());
app.use("", userRouter);
app.use("", operationsRouter);
app.use(express.static('images'));
const port = process.env.APP_PORT || 3000;
app.listen(port, () => {
console.log("server up and running on PORT :", port);
});
Hero my config file java:
const { createPool } = require("mysql");
const pool = createPool({
host: 'host.example.com',
port: 3306,
user: 'user',
password: 'password',
database: 'database',
connectionLimit: 100,
multipleStatements: true
});
module.exports = pool;
What shocked me is that why these errors show up only after deploying on Heroku?
Is there anything I can do to fix this problem?

Heroku dynamically assigns your app a port, so you can't set the port to a fixed number. Heroku adds the port to the env, so you can pull it from there. Switch your APP_PORT listen to this:
.listen(process.env.PORT || 5000)
Make sure you have changed the APP_PORT to PORT.
That way it'll still listen to port 5000 when you test locally, but it will also work on Heroku.
One more thing I can see that you are using Nodemon on Heroku which is not necessary on Heroku. So remove the Nodemon from your Heroku and declare a Procfile
web: node app.js
Being app.js the entry point to your app.

Related

conflicting port numbers in react

I have a React app where I specified the port number in server.js as
const port = process.argv[3] || 3500;
At the bottom of the same file I wrote:
app.listen(port, () => console.log(`Web service running on port ${port}`));
While the app is able to run in my browser, unfortunately in the console of my text editor it says Web service running on port 3500 even when the url says localhost:3000.
I know that React uses port 3000 as default... but don't know why the app chose to use port 3000 instead of the port 3500 that I specified above.
To try and fix this I tried to install the dev dependency cross-env and in my package.json "start" script I specified cross-env PORT=3500.
After that change, I see that my React app is now running in the browser on Port 3500... but I am unable to avoid the message from the server.js file that says "Web service running on the Port # that I specified in the server.js file".
In server.js when I use const port = process.argv[3] || 3500; in conjunction with the cross-env port 3500 change in package.json... I get the message "Something is already running on Port 3500". So it seems impossible to get the correct console message that the React app is really running properly in the browser on Port 3500.
Full Express server.js below:
const jsonServer = require("json-server");
const chokidar = require("chokidar");
const cors = require("cors");
const fileName = process.argv[2] || "./data.js";
const port = process.argv[3] || 3500;
let router = undefined;
const app = express();
const createServer = () => {
delete require.cache[require.resolve(fileName)];
setTimeout(() => {
router = jsonServer.router(fileName.endsWith(".js")
? require(fileName)() : fileName)
}, 100)
}
createServer();
app.use(cors());
app.use(jsonServer.bodyParser)
app.use("/api", (req, resp, next) => router(req, resp, next));
chokidar.watch(fileName).on("change", () => {
console.log("Reloading web service data...");
createServer()
console.log("Reloading web service data complete.");
});
app.listen(port, () => console.log(`Web service running on port ${port}`));```
Express Server:
you can run express server in the any port you want it to run
const port = process.env.port || 4000 //? can be any port number
the console log you are getting in the editor is from the server and not from the react app.
React App:
by default react app runs in port 3000 if you want to change the Port of the react app then use react-scripts like this
"start": "set PORT= <Your Desired Port> && react-scripts start"
or you can set port directly from terminal like this
PORT=4000 npm start //? or any other port number
app.listen is for express servers. To run a react server use react-scripts. To change port number use the PORT environment variable.

Is there is a way for me to host my express api on the internet?

I have recently started learning MERN stack and I made my first front-end application using React and I connected it using an API that I have created using Express. It works perfectly fine on my local machine using localhost.
But whenever I try to upload it to a hosting service, like Heroku for example, it gives me a 404 error whenever I open the link. Is there is a way for me to upload my API into a hosting service for free or is there is something I'm doing wrong in my code ?
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const app = express();
require('dotenv').config({ path: __dirname + '/.env' });
const URI = process.env.URI;
mongoose.connect(URI, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: true });
const connection = mongoose.connection;
connection.once('once', () => {
console.log('connection to database has been initiated sucessfully');
});
const itemRouter = require('./routes/itemsRouter.js');
const orderRouter = require('./routes/orderRouter.js');
const mailRouter = require('./routes/mailRouter.js');
app.use(express.json());
app.use(cors());
app.use('/items', itemRouter);
app.use('/orders', orderRouter);
app.use('/sendMail', mailRouter);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`App is running on port ${PORT}`);
});
Heroku should work out the box if you've followed the setup here Heroku Dev Center.
However, if you're using freshly shipped ubuntu or similar server. You'll need to set up the environment by doing the following:
Install node run time, nginx & a node deamon manager (In this case PM2)
sudo apt install nodejs nginx
npm install -g pm2
Create an nginx config
server {
listen 80;
index index.html;
server_name YOUR_DOMAIN/SERVER_IP;
location / {
proxy_pass 127.0.0.1:NODE_BOUND_PORT;
}
}
Deamonise the Node script
pm2 start index.js
You'll have to restart nginx and create the symbolic links for NGINX to pick up the routing but once this is done, should route as intended.

Deploying Node.JS express API App to Azure App Service

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

Can't connect to heroku postgres from heroku local using node sample

I followed the steps at:
https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction
When I ran heroku local it couldn't connect - I saw that it was using the process.env.DATABASE_URL and got it to my local .env file using:
https://devcenter.heroku.com/articles/heroku-local
But it still wouldn't connect, I've added a console.log to see the error:
"error: no pg_hba.conf entry for host "62.90.xxx.yyy", user "username", database "password", SSL off"
What now?
After a lot of searches it turns out that added 'pg.defaults.ssl = true' solves the problem for me while allowing me to stay as close as possible to the sample provided by Heroku.
Here is my code
const cool = require('cool-ascii-faces');
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 5000
const pg = require('pg');
pg.defaults.ssl = true; //this is it!!!
express()
.use(express.static(path.join(__dirname, 'public')))
.set('views', path.join(__dirname, 'views'))
....
A neat solution would be enabling SSL only for the Heroku server connection. For that add dialectOptions.ssl=true to Heroku environment in config.json file:
{
"production": {
"use_env_variable": "DATABASE_URL",
"dialectOptions": { "ssl": true },
"logging": false
}

What is the use of setting a port in gulp-nodemon?

I am using gulp-nodemon because of its most obvious of utilities.
Nodemon is a utility that will monitor for any changes
in your source and automatically restart your server.
But I am not understanding a practice which seems to be prevalent in express/node development.
I just started working with node and express but from what I understand:
app.js
var express = require('express'),
app = express(),
port = process.env.PORT || 8016;
app.get('/', function rootHndlr(req, res) {
/* body... */
res.send('welcome to my API!');
});
app.listen(port, function listenHndlr(){
console.log('Gulp is running my app on PORT ' + port);
});
The following is setting in the port to 8016 if not set.
port = process.env.PORT || 8016;
So now we binds and listens for connections on the specified host and port.
But then I see people configure in their gulp tasks the following to nodemon in their gulpfile.js
gulpfile.js
var gulp = require('gulp'),
nodemon = require('gulp-nodemon');
gulp.task('default', function() {
// content
nodemon({
script: 'app.js',
ext: 'js'
env: {
PORT: 8000
},
ignore: ['./node_modules/**']
}).
on('restart', function(){
consile.log('Restarting');
});
});
As you can one of the values in nodemon env: {PORT: 8000} Why set the port again?
Thanks!
People are using something like that as a fallback: port = process.env.PORT || 8016;
Your application should be flexible enough and by passing an env var to make it listen to another port. In general, this is the purpose of the env vars.
About your example, I suppose that there is a reason that the guy that wrote this gulpfile would like to make the app listen to port 8000. I would say that it is safe to change the value or to remove the PORT: 8000 as soon as you are 100% sure that there is no reason that the application needs to run on port 8000 (for example, it is behind a reverse proxy that forwards the traffic to port 8000).

Resources