最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Puppeteer Not Working in Node.js Project After Deployment to Azure (Works Locally) - Stack Overflow

programmeradmin0浏览0评论

I am using Puppeteer in my Node.js project, and it works perfectly fine on my local machine. However, after deploying the project to Azure, I am encountering issues where Puppeteer does not seem to function properly.

Issue:

The error message I get is:

Could not find Chrome (ver. 131.0.6778.85). This can occur if either
 1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install chrome`) or
 2. your cache path is incorrectly configured (which is: /root/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at /guides/configuration.

This suggests that Puppeteer is unable to locate a Chromium instance in the Azure environment.

Environment Details:

Local Machine: Works fine without any issues.

Azure Deployment: Fails to find Chrome.

Steps I Have Tried:

Installing Puppeteer with Chromium:

npm install puppeteer

Setup the api

app.get("/_api/screenshot", async (req, res) => {
  try {
    // Get the URL from query string, default to example if not provided
    const targetUrl = req.query.url || ";;

    console.log("Starting browser launch...");

    // Launch Puppeteer with necessary arguments for cloud environments
    const browser = await puppeteer.launch({
      headless: true,
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-dev-shm-usage",
        "--single-process",
        "--no-zygote",
      ],
      // Use the path from environment variable or let Puppeteer find it
      executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
    });

    console.log("Browser launched successfully");

    const page = await browser.newPage();
    console.log("Navigating to:", targetUrl);

    // Navigate to the target URL and wait until network is idle
    await page.goto(targetUrl, { waitUntil: "networkidle0" });
    console.log("Page loaded, taking screenshot");

    // Take a screenshot as a base64 string
    const screenshotBuffer = await page.screenshot({ encoding: "base64" });
    console.log("Screenshot taken, closing browser");

    await browser.close();

    // Return the screenshot as an HTML image
    res.send(`<img src="data:image/png;base64,${screenshotBuffer}" />`);
  } catch (error) {
    console.error("Error in /api/screenshot:", error);
    res.status(500).json({
      error: "Failed to take screenshot",
      message: error.message,
      stack: error.stack,
      puppeteerInfo: process.env.PUPPETEER_EXECUTABLE_PATH || "No path set",
    });
  }
});

But still getting the above error

Note: We're using the Github workflow to deploy the updated code to Azure, if anyone know or have done this please let us know what will be proper method to do this, would be great help :)

Following is my .yml file

name: app-name

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Cache Node modules
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: "22.x"

      - name: Install dependencies
        run:
          npm ci

          # Add the Prepare for Puppeteer step here
      - name: Prepare for Puppeteer
        run: |
          npm uninstall puppeteer-core
          npm install puppeteer
          npx puppeteer browsers install chrome
          echo "PUPPETEER_EXECUTABLE_PATH=$(node -e 'console.log(require(\"puppeteer\").executablePath())')" >> .env

      - name: Create startup script
        run: |
          echo '#!/bin/bash
          echo "Listing directory contents to debug:"
          ls -la /home/site/wwwroot
          echo ""
          echo "Installing Chrome dependencies..."
          apt-get update && apt-get install -y \
              libx11-xcb1 \
              libxcomposite1 \
              libxcursor1 \
              libxdamage1 \
              libxi6 \
              libxtst6 \
              libnss3 \
              libcups2 \
              libxss1 \
              libxrandr2 \
              libasound2 \
              libatk1.0-0 \
              libatk-bridge2.0-0 \
              libpangocairo-1.0-0 \
              libgtk-3-0 \
              libgbm1

          echo "Starting Node.js application..."
          # Try server.js first, fall back to index.js, then try app.js
          if [ -f "/home/site/wwwroot/server.js" ]; then
            node server.js
          elif [ -f "/home/site/wwwroot/index.js" ]; then
            node index.js
          elif [ -f "/home/site/wwwroot/app.js" ]; then
            node app.js
          else
            echo "No main entry file found. Looking for JavaScript files:"
            find /home/site/wwwroot -name "*.js" -type f | head -10
            exit 1
          fi' > startup.sh
          chmod +x startup.sh

      - name: Zip artifact for deployment
        run: zip release.zip . -r

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        with:
          name: node-app
          path: release.zip

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: "Production"
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    permissions:
      id-token: write
      contents: read

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: node-app

      - name: Login to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_ }}
          tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_ }}
          subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_2F56DD }}

      - name: "Deploy to Azure Web App"
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v3
        with:
          app-name: "app-name"
          slot-name: "Production"
          package: release.zip

      - name: Configure startup command
        uses: azure/[email protected]
        with:
          inlineScript: |
            az webapp config set --resource-group AppName --name project_name --startup-file "bash startup.sh"

I am using Puppeteer in my Node.js project, and it works perfectly fine on my local machine. However, after deploying the project to Azure, I am encountering issues where Puppeteer does not seem to function properly.

Issue:

The error message I get is:

Could not find Chrome (ver. 131.0.6778.85). This can occur if either
 1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install chrome`) or
 2. your cache path is incorrectly configured (which is: /root/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.

This suggests that Puppeteer is unable to locate a Chromium instance in the Azure environment.

Environment Details:

Local Machine: Works fine without any issues.

Azure Deployment: Fails to find Chrome.

Steps I Have Tried:

Installing Puppeteer with Chromium:

npm install puppeteer

Setup the api

app.get("/_api/screenshot", async (req, res) => {
  try {
    // Get the URL from query string, default to example if not provided
    const targetUrl = req.query.url || "https://example";

    console.log("Starting browser launch...");

    // Launch Puppeteer with necessary arguments for cloud environments
    const browser = await puppeteer.launch({
      headless: true,
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-dev-shm-usage",
        "--single-process",
        "--no-zygote",
      ],
      // Use the path from environment variable or let Puppeteer find it
      executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
    });

    console.log("Browser launched successfully");

    const page = await browser.newPage();
    console.log("Navigating to:", targetUrl);

    // Navigate to the target URL and wait until network is idle
    await page.goto(targetUrl, { waitUntil: "networkidle0" });
    console.log("Page loaded, taking screenshot");

    // Take a screenshot as a base64 string
    const screenshotBuffer = await page.screenshot({ encoding: "base64" });
    console.log("Screenshot taken, closing browser");

    await browser.close();

    // Return the screenshot as an HTML image
    res.send(`<img src="data:image/png;base64,${screenshotBuffer}" />`);
  } catch (error) {
    console.error("Error in /api/screenshot:", error);
    res.status(500).json({
      error: "Failed to take screenshot",
      message: error.message,
      stack: error.stack,
      puppeteerInfo: process.env.PUPPETEER_EXECUTABLE_PATH || "No path set",
    });
  }
});

But still getting the above error

Note: We're using the Github workflow to deploy the updated code to Azure, if anyone know or have done this please let us know what will be proper method to do this, would be great help :)

Following is my .yml file

name: app-name

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Cache Node modules
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: "22.x"

      - name: Install dependencies
        run:
          npm ci

          # Add the Prepare for Puppeteer step here
      - name: Prepare for Puppeteer
        run: |
          npm uninstall puppeteer-core
          npm install puppeteer
          npx puppeteer browsers install chrome
          echo "PUPPETEER_EXECUTABLE_PATH=$(node -e 'console.log(require(\"puppeteer\").executablePath())')" >> .env

      - name: Create startup script
        run: |
          echo '#!/bin/bash
          echo "Listing directory contents to debug:"
          ls -la /home/site/wwwroot
          echo ""
          echo "Installing Chrome dependencies..."
          apt-get update && apt-get install -y \
              libx11-xcb1 \
              libxcomposite1 \
              libxcursor1 \
              libxdamage1 \
              libxi6 \
              libxtst6 \
              libnss3 \
              libcups2 \
              libxss1 \
              libxrandr2 \
              libasound2 \
              libatk1.0-0 \
              libatk-bridge2.0-0 \
              libpangocairo-1.0-0 \
              libgtk-3-0 \
              libgbm1

          echo "Starting Node.js application..."
          # Try server.js first, fall back to index.js, then try app.js
          if [ -f "/home/site/wwwroot/server.js" ]; then
            node server.js
          elif [ -f "/home/site/wwwroot/index.js" ]; then
            node index.js
          elif [ -f "/home/site/wwwroot/app.js" ]; then
            node app.js
          else
            echo "No main entry file found. Looking for JavaScript files:"
            find /home/site/wwwroot -name "*.js" -type f | head -10
            exit 1
          fi' > startup.sh
          chmod +x startup.sh

      - name: Zip artifact for deployment
        run: zip release.zip . -r

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        with:
          name: node-app
          path: release.zip

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: "Production"
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    permissions:
      id-token: write
      contents: read

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: node-app

      - name: Login to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_ }}
          tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_ }}
          subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_2F56DD }}

      - name: "Deploy to Azure Web App"
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v3
        with:
          app-name: "app-name"
          slot-name: "Production"
          package: release.zip

      - name: Configure startup command
        uses: azure/[email protected]
        with:
          inlineScript: |
            az webapp config set --resource-group AppName --name project_name --startup-file "bash startup.sh"
Share Improve this question edited Mar 13 at 8:32 Akshay Pagare asked Mar 13 at 6:50 Akshay PagareAkshay Pagare 1523 silver badges10 bronze badges 2
  • Please share your .yml file. – Sirra Sneha Commented Mar 13 at 7:17
  • @SirraSneha I've added .yml file, Thankyou for your time. – Akshay Pagare Commented Mar 13 at 8:33
Add a comment  | 

1 Answer 1

Reset to default 1

I've created a sample Node.js project using Puppeteer to launch a headless browser and take a screenshot of a webpage.

I got the same issue when I deployed to Azure App Service, to resolve the issue I've added the below startup command in the configuration section of my web app.

apt-get update && apt-get install -y wget && wget -q -O - https://dl.google/linux/linux_signing_key.pub | apt-key add - && echo "deb [arch=amd64] http://dl.google/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list && apt-get update && apt-get install -y google-chrome-stable && node server.js

Add the below environment variables in your Azure app service.

server.js:

require("dotenv").config();
const express = require("express");
const puppeteer = require("puppeteer");
const fs = require("fs");

const app = express();
const PORT = process.env.PORT || 3000;

app.get("/screenshot", async (req, res) => {
  try {
    const targetUrl = req.query.url || "https://example";

    console.log("Launching Puppeteer...");
    const browser = await puppeteer.launch({
      headless: "new",
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-dev-shm-usage",
        "--single-process",
        "--no-zygote",
      ],
      executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || puppeteer.executablePath(),
    });

    const page = await browser.newPage();
    await page.goto(targetUrl, { waitUntil: "networkidle0" });

    const screenshotPath = "screenshot.png";
    await page.screenshot({ path: screenshotPath });

    await browser.close();

    res.sendFile(screenshotPath, { root: __dirname }, (err) => {
      if (err) {
        console.error("Error sending file:", err);
        res.status(500).json({ error: "Failed to send screenshot" });
      } else {
        console.log("Screenshot successfully sent.");
      }
    });

  } catch (error) {
    console.error("Error:", error);
    res.status(500).json({ error: error.message });
  }
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Workflow file:

name: Build and deploy Node.js app to Azure Web App - puppetternode18

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: '20.x'

      - name: Install system dependencies for Puppeteer
        run: |
          sudo apt-get update
          sudo apt-get install -y google-chrome-stable \
            libnss3 libxss1 libasound2t64 libatk1.0-0 \
            libatk-bridge2.0-0 libcups2 libdrm2 libgbm1 \
            libgtk-3-0 libnspr4 libxcomposite1 libxcursor1 \
            libxdamage1 libxfixes3 libxrandr2 libxrender1 \
            libxshmfence1
      - name: Set Puppeteer environment variables
        run: |
          echo "PUPPETEER_SKIP_DOWNLOAD=false" >> $GITHUB_ENV
          echo "PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable" >> $GITHUB_ENV
      - name: Install dependencies, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present
      - name: Zip artifact for deployment
        run: zip release.zip ./* -r

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        with:
          name: node-app
          path: release.zip

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: node-app

      - name: Unzip artifact for deployment
        run: unzip release.zip

      - name: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v3
        with:
          app-name: 'puppetternode18'
          slot-name: 'Production'
          package: .
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_705EF5D45F054804AA01E0B93B6AF9D7 }}

I've successfully deployed my application to Azure app service via GitHub actions.

Production output:

发布评论

评论列表(0)

  1. 暂无评论