Search code examples
node.jsazureazure-web-app-servicebcrypt

My mern project is not running in azure web app


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 :

bcrypt installation error

node index.js command error

url error

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"
  }
}

Solution

  • 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:
    enter image description here