Complete Guide: Installing Puppeteer on cPanel with CloudLinux Node.js Selector

Shahid

May 20, 2025 . 10 min read

By Shahid | May 20, 2025 | 8 min read

Introduction

Are you looking to automate browser tasks directly from your cPanel hosting? If your goal is to set up browser automation on your cPanel server, then we’ve got the right guide for you. Using CloudLinux Node.js Selector, we will detail how to configure Puppeteer for taking screenshots, content scraping, and task automation all via your hosting account.

Puppeteer has become the go-to solution for web automation tasks, allowing developers to control headless Chrome or Chromium browsers programmatically. When combined with cPanel and CloudLinux Node.js Selector, you can create powerful web automation solutions directly from your hosting environment.

Prerequisites

Before diving into the installation process, ensure you have the following:

  • A Node.js Selector enabled cPanel hosting account with CloudLinux
  • Login credentials to SSH into your hosting account
  • A preconfigured Node.js Application in cPanel (or follow our steps to set one up)
  • Basic understanding of JavaScript and Node.js concepts

Setting Up Your First Node.js Application (If Needed)

For those who don’t have an existing Node.js application on cPanel, complete the following actions:

  1. Access cPanel
  2. Look for the “Node JS App” icon in the “Software” area
  3. Click on the icon to launch the Node JS selector
  4. Click the “Add Application” option
  5. Fill in the details as follows:
    • Application root: Choose a directory for the app such as /home/yourusername/nodeapp
    • App URL: Define the target application URL path
    • App Start File: Typically it is “server.js” or “app.js”
    • Node.js Version: Choose the most relevant stable version (v14 or newer recommended)
  6. Click on “Add” and you will have Node.js ready for use

Once your Node.js application is created in cPanel, you’ll see it listed in the Node.js Selector interface. Now you’re ready to proceed with Puppeteer installation.

Getting Started: Accessing Your Server

First, connect to your server using SSH:

ssh yourusername@your-domain.com

Once connected, navigate to your Node.js application directory:

cd /home/yourusername/yourappfolder

Activating Your Node.js Environment

CloudLinux uses virtual environments to isolate Node.js applications. Before working with Node.js, you’ll need to activate the appropriate environment:

source /home/yourusername/nodevenv/yourappname/version/bin/activate

For example:

source /home/yourusername/nodevenv/nodeproxy/19/bin/activate

Your command prompt will change to show you’re in the activated environment:

[yourappname (version)] [yourusername@server yourappfolder]$

Verifying Your Node.js Setup

Ensure Node.js and npm are properly available in your environment:

node -v
npm -v

You should see version numbers displayed, confirming both tools are ready to use.

Installing Puppeteer

Now, install Puppeteer with a simple npm command:

npm install puppeteer

This might take several minutes as it downloads Chromium, the browser engine Puppeteer uses to perform its magic. The total size is approximately 170MB depending on your platform.

Confirming Successful Installing Puppeteer on cPanel

Verify that Puppeteer installed correctly by checking its files:

ls -la ~/nodevenv/yourappname/version/lib/node_modules/puppeteer

You should see several files and folders, including package.json, lib, and src directories.

Creating Your First Puppeteer Script

Let’s create a test script to ensure everything works:

nano test-puppeteer.js

Add this code to your new file:

const puppeteer = require('puppeteer');

(async () => {
  console.log('Launching Puppeteer...');
  try {
    // Configure browser with optimized settings for shared hosting
    const browser = await puppeteer.launch({
      headless: true,
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-accelerated-2d-canvas',
        '--disable-gpu'
      ]
    });
    console.log('Browser successfully launched');
    
    const page = await browser.newPage();
    console.log('New page created');
    
    await page.goto('https://example.com');
    console.log('Page loaded successfully');
    
    const title = await page.title();
    console.log('Page title retrieved:', title);
    
    await browser.close();
    console.log('Browser closed properly');
  } catch (error) {
    console.error('Error encountered:', error);
  }
})();

Running Your Test Script

Execute your script to verify Puppeteer works correctly:

node test-puppeteer.js

If successful, you’ll see a series of log messages showing each step completing properly, similar to:

Launching Puppeteer...
Browser successfully launched
New page created
Page loaded successfully
Page title retrieved: Example Domain
Browser closed properly

Integrating Puppeteer Into Your Web Application

Now that you’ve confirmed Puppeteer works, you can integrate it into your main application. Edit your server file:

nano server.js

Add these powerful Puppeteer-based endpoints to your Express application:

const express = require('express');
const puppeteer = require('puppeteer');
const app = express();

// Your existing code...

// Screenshot API endpoint
app.get('/screenshot', async (req, res) => {
  const url = req.query.url;
  
  if (!url) {
    return res.status(400).send('Please provide a URL parameter');
  }
  
  let browser;
  try {
    browser = await puppeteer.launch({
      headless: true,
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage'
      ]
    });
    
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });
    
    const screenshot = await page.screenshot({ type: 'png' });
    
    res.set('Content-Type', 'image/png');
    res.send(screenshot);
  } catch (error) {
    console.error('Screenshot error:', error);
    res.status(500).send('Unable to capture screenshot');
  } finally {
    if (browser) {
      await browser.close();
    }
  }
});

// HTML content renderer endpoint
app.get('/render', async (req, res) => {
  const url = req.query.url;
  
  if (!url) {
    return res.status(400).send('Please provide a URL parameter');
  }
  
  let browser;
  try {
    browser = await puppeteer.launch({
      headless: true,
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage'
      ]
    });
    
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });
    
    const content = await page.content();
    
    res.set('Content-Type', 'text/html');
    res.send(content);
  } finally {
    if (browser) {
      await browser.close();
    }
  }
});

// Your existing code continues...

Activating Your Enhanced Application

Return to your cPanel Node.js Application Manager and restart your application to apply the changes:

  1. Go to cPanel > Software > Node.js App
  2. Find your application in the list
  3. Click the “Restart” button next to your application
  4. Wait for the status to change to “Running”

Testing Your New Puppeteer Features

Try accessing your new endpoints with a browser:

https://your-domain.com/screenshot?url=https://example.com
https://your-domain.com/render?url=https://example.com

The first URL will return a PNG screenshot of example.com, while the second will return the fully rendered HTML content.

Troubleshooting Common Issues

Browser Launch Failures

If Chromium doesn’t launch properly, try using puppeteer-core instead:

npm uninstall puppeteer
npm install puppeteer-core

Then modify your code to use an existing Chrome installation:

const puppeteer = require('puppeteer-core');

const browser = await puppeteer.launch({
  executablePath: '/usr/bin/google-chrome',  // Adjust path as needed
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage'
  ]
});

Memory Management

For better performance on shared hosting, optimize resource usage:

const browser = await puppeteer.launch({
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
    '--memory-pressure-off',
    '--single-process',
    '--disable-extensions',
    '--disable-component-extensions-with-background-pages',
    '--disable-default-apps',
    '--mute-audio'
  ]
});

Consider implementing a browser pool to reuse browser instances rather than creating new ones for each request. This approach can significantly reduce memory usage and improve response times:

// Simple browser pool implementation
const puppeteer = require('puppeteer');

class BrowserPool {
  constructor(maxSize = 2) {
    this.browsers = [];
    this.maxSize = maxSize;
    this.inUse = new Set();
  }

  async getBrowser() {
    // Check for available browsers
    const availableBrowser = this.browsers.find(b => !this.inUse.has(b));
    
    if (availableBrowser) {
      this.inUse.add(availableBrowser);
      return availableBrowser;
    }
    
    // Create new browser if below max size
    if (this.browsers.length < this.maxSize) {
      const newBrowser = await puppeteer.launch({
        headless: true,
        args: [
          '--no-sandbox',
          '--disable-setuid-sandbox',
          '--disable-dev-shm-usage'
        ]
      });
      
      this.browsers.push(newBrowser);
      this.inUse.add(newBrowser);
      return newBrowser;
    }
    
    // Wait for a browser to become available
    return new Promise(resolve => {
      const checkInterval = setInterval(() => {
        const availableBrowser = this.browsers.find(b => !this.inUse.has(b));
        if (availableBrowser) {
          clearInterval(checkInterval);
          this.inUse.add(availableBrowser);
          resolve(availableBrowser);
        }
      }, 100);
    });
  }

  releaseBrowser(browser) {
    this.inUse.delete(browser);
  }

  async closeAll() {
    await Promise.all(this.browsers.map(browser => browser.close()));
    this.browsers = [];
    this.inUse.clear();
  }
}

// Usage example
const pool = new BrowserPool(3);
// In your request handler:
const browser = await pool.getBrowser();
try {
  // Use the browser
} finally {
  pool.releaseBrowser(browser);
}

Pro Tips for Daily Use

Convenient Environment Activation

To avoid manually activating the Node.js environment each time you log in, add this to your .bashrc file:

echo 'source /home/yourusername/nodevenv/yourappname/version/bin/activate' >> ~/.bashrc

Recommended Protocols for Best Practices in Production

Use of Resources

  • Allocate clients with limits on concurrent instances (browser pool) to prevent memory spill over
  • Use the --single-process flag for lower memory usage but be aware this makes Puppeteer less stable
  • Implement request queuing for high-traffic applications

Application Stability and Reliability

  • Ensure the application is responsive by adding timeouts and thorough error catching
  • Implement health checks to automatically restart browsers that have become unresponsive
  • Use process managers like PM2 to keep your application running

Security Considerations

  • AVOID security holes by validating URLs prior to using them with Puppeteer
  • Implement URL whitelisting to prevent access to internal network resources
  • Sanitize all user inputs to prevent command injection attacks

Change Control

  • Reduce server load by caching frequently fetched content
  • Implement cache invalidation strategies for dynamic content
  • Use a CDN for serving generated screenshots when possible

Abuse Prevention

  • Protect your server from excessive requests by adding rate limits
  • Implement user authentication for your Puppeteer-powered APIs
  • Monitor and log all requests to detect abuse patterns

FAQs About Puppeteer on cPanel

Q: How much memory does Puppeteer typically use on cPanel?

A: Each Puppeteer instance with Chromium can use between 200-300MB of RAM, depending on the complexity of the pages being rendered. Using a browser pool can help manage this resource effectively.

Q: Can I use Puppeteer to automate form submissions on websites?

A: Yes, Puppeteer provides robust capabilities for form interaction, including filling fields, clicking buttons, and handling authentication. Here’s a simple example:

await page.type('#username', 'myusername');
await page.type('#password', 'mypassword');
await page.click('#login-button');
await page.waitForNavigation();

Q: Does Puppeteer work with JavaScript-heavy single-page applications?

A: Absolutely! Puppeteer is particularly well-suited for SPAs as it fully executes JavaScript. Use the waitForSelector or waitForFunction methods to ensure the page has loaded completely before interacting with elements.

Q: How can I handle CAPTCHA challenges when using Puppeteer?

A: For legitimate use cases, consider:

  1. Using CAPTCHA solving services via their APIs
  2. Implementing manual intervention for critical flows
  3. Requesting API access from the target website when possible

Q: Is it possible to generate PDFs with Puppeteer on cPanel?

A: Yes, use the page.pdf() method:

const pdf = await page.pdf({
  format: 'A4',
  printBackground: true,
  margin: {
    top: '1cm',
    right: '1cm',
    bottom: '1cm',
    left: '1cm'
  }
});

Conclusion

Installation guide for the Puppetter By using this elaborate guide, you are ready to have Puppeteer up and running on your cPanel server. You can now automate your browser (take screenshots, extract content, perform web testing, etc.) directly from your web hosting.

Puppeteer combined with Node.js and CloudLinux makes a great combination to easily develop advanced web automation solutions without needing dedicated server resources. From taking simple screenshots to performing complex web scraping, the possiblities are now endless with Puppeteer on cPanel.

Do remember to implement the best practices according to the guide, especially when it comes to efficient resource management and security, so you can Puppeteer functionality remains performant and secure in a production environment.

Have you implemented Puppeteer on your cPanel server? Share your experience or questions in the comments below!