Install

npm install puppeteer

Minimal example

import puppeteer from 'puppeteer';

const auth = `${process.env.AVP_KEY}:${process.env.AVP_SECRET}`;

const browser = await puppeteer.launch({
  args: ['--proxy-server=http://api.atlasvpn.live:7777'],
});

const page = await browser.newPage();

// Auth via page.authenticate — Chromium's proxy-server arg doesn't
// accept user:pass@host:port inline; you have to authenticate via the
// DevTools protocol.
await page.authenticate({
  username: process.env.AVP_KEY,      // avp_live_...
  password: process.env.AVP_SECRET,   // 64-char hex
});

await page.goto('https://ifconfig.me');
console.log(await page.content());
// → a residential IP

await browser.close();

Sticky session

Puppeteer inherits Chromium’s single-proxy-per-browser model. To use a sticky session, embed the tag in the username:
const sessionTag = `scrape-${Date.now()}`;
await page.authenticate({
  username: `avp_live_<key>-country-us-session-${sessionTag}`,
  password: '<secret>',
});

// All subsequent requests from this page use the same US residential
// exit for 10 minutes.
One Puppeteer browser instance = one sticky session. To rotate IPs, launch a fresh browser with a different username (-session-<newTag>). Browser launch is slow (~1s) so batch your scraping runs to minimise restarts.

Rotating IPs per-page

async function scrapeWithFreshIp(url) {
  const tag = Math.random().toString(36).slice(2, 10);
  const browser = await puppeteer.launch({
    args: ['--proxy-server=http://api.atlasvpn.live:7777'],
  });
  const page = await browser.newPage();
  await page.authenticate({
    username: `avp_live_<key>-country-fr-session-${tag}`,
    password: '<secret>',
  });
  try {
    await page.goto(url, { waitUntil: 'networkidle2' });
    return await page.content();
  } finally {
    await browser.close();
  }
}

Handling anti-bot tech

Puppeteer through a residential IP defeats IP-based bot detection but NOT behavioural detection (mouse movement, timing, fingerprinting). For those, add:
  • puppeteer-extra-plugin-stealth — patches common bot-detection tells
  • human-like delaysawait page.waitForTimeout(randint(500, 2000))
  • Real user-agent rotation — match Chrome versions currently in market
Residential IP + stealth plugin + realistic timing beats most commercial bot-detection products. The exceptions are the most advanced ones (PerimeterX, Datadome, Arkose Labs) — those require dedicated anti-bot SaaS.

Chromium + Docker

FROM node:20-slim

RUN apt-get update && apt-get install -y \
    ca-certificates chromium fonts-liberation libappindicator1 \
    libasound2 libatk-bridge2.0-0 libatk1.0-0 libcups2 libdbus-1-3 \
    libgbm1 libgtk-3-0 libnspr4 libnss3 libx11-xcb1 libxcomposite1 \
    libxdamage1 libxrandr2 xdg-utils --no-install-recommends

WORKDIR /app
COPY package*.json ./
RUN npm ci --production

COPY . .
CMD ["node", "scrape.js"]
Pass AVP_KEY and AVP_SECRET as env vars at run-time, NEVER bake them into the image.