i created a project with frontend react vite and backend with node js, the project is running on the local machine with same node version but not running on azure, in azure deployment center the project is successfully deployed the logs showing :
AppInsightsAgent: Successfully loaded ETW AppInsightsAgent ETWLogger Application Insights was started succesfully. Using start-up script index.js from package.json. Generated web.config. The package.json file does not specify node.js engine version constraints. The node.js application will run with the default node.js version 20.9.0. Selected npm version 10.1.0 AppInsightsAgent: Successfully loaded ETW AppInsightsAgent ETWLogger Application Insights was started succesfully. npm WARN config production Use --omit=dev instead.
up to date, audited 189 packages in 1s
20 packages are looking for funding
run npm fund for details
found 0 vulnerabilities
Finished successfully.`
but when i am clicking on the default domain link it is showing currently unable to handle this request. HTTP ERROR 500
: i also checked the console terminal of the my app , when i tried to open the index.js file with node index.js it showing this error :
`node:internal/errors:497
ErrorCaptureStackTrace(err);
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'bcrypt' imported from C:\home\site\wwwroot\Routes\AdminRoute.js
at new NodeError (node:internal/errors:406:5)
at packageResolve (node:internal/modules/esm/resolve:789:9)
at moduleResolve (node:internal/modules/esm/resolve:838:20)
at defaultResolve (node:internal/modules/esm/resolve:1043:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:383:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:352:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:228:38)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
at link (node:internal/modules/esm/module_job:84:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
Node.js v20.9.0
AppInsightsAgent: Successfully loaded ETW
AppInsightsAgent ETWLogger Application Insights was started succesfully.`
i also installed the same node version of azure in my local machine and project is running in the local machine, but not in azure. i am also unable to install the bcrypt package :
the web app OS is windows
i tried to run the applicatiion multiple times and it is still showing the same error , if the i also added the version of node in package.json file but the azure don't have that version of node.
package.json file
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.19.2",
"jsonwebtoken": "^9.0.2",
"multer": "^1.4.5-lts.1",
"mysql": "^2.18.1",
"nodemon": "^3.1.4",
"path": "^0.12.7"
},
"engines": {
"node": "20.15.0"
}
}
I tried a sample code with your packages and got the same error due to bcrypt
package.I reason for Azure Web App failing/ didn’t run in azure when bcrypt is used are explained in this link.This can be resloved by usingbcryptjs
It a Optimized bcrypt in JavaScript with zero dependencies. Compatible to the C++ bcrypt binding on node.js and also working in the browser.
To install bcryptjs
, use the following command:
npm install bcryptjs
import bcrypt from 'bcryptjs';
const bcrypt = require('bcryptjs');
One more thing to note before deploying to Azure is your Azure Node version is 20.9.0
, and your local Node version is 20.15.0
. Make the version equal to or less than the Azure version by using the method shown below.
"engines": {
"node": "20.x"
}
The sample Express.js code below demonstrates user registration, authentication, file uploads, and a protected route that requires JWT-based authentication using bcryptjs
.
I have refered this link to build and deploy a Node.js Express app to Azure Cloud Services.
const express = require('express');
const bcrypt = require('bcryptjs');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const jwt = require('jsonwebtoken');
const multer = require('multer');
const mysql = require('mysql');
const path = require('path');
const fs = require('fs');
const PORT = process.env.PORT || 3001;
const SECRET_KEY = 'your_secret_key';
const app = express();
app.use(express.json());
app.use(cookieParser());
app.use(cors());
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname));
}
});
const upload = multer({ storage });
const db = mysql.createConnection({
host: 'HostName',
user: 'UserName',
password: 'Password',
database: 'DatabaseName',
ssl: {ca: fs.readFileSync("your_path_to_ca_cert_file_DigiCertGlobalRootCA.crt.pem")}
});
db.connect(err => {
if (err) {
console.error('Error connecting to MySQL:', err);
return;
}
console.log('Connected to MySQL database');
});
app.post('/register', async (req, res) => {
const { username, password } = req.body;
try {
const hashedPassword = await bcrypt.hash(password, 10);
db.query('INSERT INTO users (username, password) VALUES (?, ?)', [username, hashedPassword], (err) => {
if (err) return res.status(500).json({ error: 'Database error' });
res.status(201).json({ message: 'User registered successfully' });
});
} catch (err) {
res.status(500).json({ error: 'Server error' });
}
});
app.post('/login', (req, res) => {
const { username, password } = req.body;
db.query('SELECT * FROM users WHERE username = ?', [username], async (err, results) => {
if (err || results.length === 0) return res.status(401).json({ error: 'Invalid credentials' });
const user = results[0];
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(401).json({ error: 'Invalid credentials' });
// Generate JWT
const token = jwt.sign({ userId: user.id }, SECRET_KEY, { expiresIn: '1h' });
res.cookie('token', token, { httpOnly: true });
res.json({ message: 'Logged in successfully' });
});
});
app.post('/upload', upload.single('file'), (req, res) => {
if (!req.file) return res.status(400).json({ error: 'No file uploaded' });
res.status(200).json({ message: 'File uploaded successfully', file: req.file });
});
app.get('/protected', (req, res) => {
const token = req.cookies.token;
if (!token) return res.status(401).json({ error: 'Access denied, no token provided' });
jwt.verify(token, SECRET_KEY, (err, decoded) => {
if (err) return res.status(401).json({ error: 'Invalid token' });
res.json({ message: 'Access granted', userId: decoded.userId });
});
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
web.config:
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="index.js" verb="*" modules="iisnode" />
</handlers>
</system.webServer>
</configuration>
Azure web app output: