클라우드에서 Puppeteer를 자유롭게 실행하는 방법: 솔루션 비교
James Reed
Infrastructure Engineer · Leapcell

Puppeteer는 웹 페이지와의 인간 상호 작용을 시뮬레이션할 수 있는 강력한 도구로, 웹 페이지 스크린샷, PDF 생성, 자동화된 테스트, 가동 시간 모니터링, 웹 스크래핑 및 콘텐츠 추적과 같은 다양한 사용 사례를 가능하게 합니다.
클라우드에 Puppeteer를 배포하는 것이 합리적인 경우는 많습니다. 예를 들어:
- CI/CD 파이프라인에서 API를 통해 자동화된 테스트를 트리거합니다.
- cron 작업을 사용하여 웹사이트 가용성을 주기적으로 확인합니다.
- 대규모 분산 웹 스크래퍼를 실행합니다.
종량제 방식과 확장 가능한 서버리스 컴퓨팅은 브라우저 자동화 작업에 탁월한 선택입니다. 그러나 DigitalOcean과 같은 대부분의 플랫폼은 가상 머신만 제공하므로 유휴 시간에 대한 비용을 지불해야 합니다(이는 많은 돈을 낭비하게 됩니다!). 현재 몇 안 되는 플랫폼만이 서버리스 방식으로 Puppeteer 실행을 지원합니다. Leapcell, AWS Lambda 및 Cloudflare Browser Rendering입니다.
이 기사에서는 이러한 플랫폼을 살펴봅니다. 일반적인 Puppeteer 작업을 수행하는 방법과 장단점을 알아봅니다.
작업
일반적인 Puppeteer 사용 사례를 예로 들어 보겠습니다. 웹 페이지의 스크린샷을 캡처하는 것입니다.
이 작업에는 다음 단계가 포함됩니다.
- 지정된 URL을 방문합니다.
- 페이지의 스크린샷을 찍습니다.
- 이미지를 반환합니다.
Leapcell
코드 예시:
const puppeteer = require('puppeteer'); const { Hono } = require('hono'); const { serve } = require('@hono/node-server'); const screenshot = async (url) => { const browser = await puppeteer.launch({ args: ['--single-process', '--no-sandbox'] }); const page = await browser.newPage(); await page.goto(url); const img = await page.screenshot(); await browser.close(); return img; }; const app = new Hono(); app.get('/', async (c) => { const url = c.req.query('url'); if (url) { const img = await screenshot(url); return c.body(img, { headers: { 'Content-Type': 'image/png' } }); } else { return c.text('Please add an ?url=https://example.com/ parameter'); } }); const port = 8080; serve({ fetch: app.fetch, port }).on('listening', () => { console.log(`Server is running on port ${port}`); });
Leapcell은 모든 애플리케이션을 서버리스 방식으로 배포할 수 있는 다재다능한 플랫폼입니다. 그러나 HTTP 요청 전용으로 설계되지 않았기 때문에 설정이 약간 더 복잡할 수 있습니다. HTTP 요청 처리기를 수동으로 만들어야 합니다.
로컬 개발
디버깅은 간단합니다. 다른 Node.js 애플리케이션과 마찬가지로 node index.js
를 실행하면 됩니다!
배포
배포하려면 빌드 명령어, 실행 명령어 및 서비스 포트를 지정합니다(아래 스크린샷과 같이).
Puppeteer는 종속성을 자동으로 설치하지 않으므로 빌드 명령어를 다음과 같이 변경해야 합니다.
apt update && apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libnss3 lsb-release xdg-utils wget npm install
배포가 완료되면 애플리케이션을 온라인에서 사용할 수 있습니다.
요약
✅ 장점:
- 일관된 로컬 및 클라우드 환경으로 디버깅이 더 쉽습니다.
- 공식 Puppeteer 라이브러리를 지원합니다.
❌ 단점:
- 약간 더 복잡한 설정: HTTP 처리기를 직접 작성해야 합니다.
AWS Lambda
코드 예시:
const chromium = require('chrome-aws-lambda'); exports.handler = async (event) => { let browser = null; try { browser = await chromium.puppeteer.launch({ args: chromium.args, defaultViewport: chromium.defaultViewport, executablePath: await chromium.executablePath, headless: chromium.headless, }); const page = await browser.newPage(); await page.goto(event.url); const screenshot = await page.screenshot(); return { statusCode: 200, headers: { 'Content-Type': 'image/jpeg' }, body: screenshot.toString('base64'), isBase64Encoded: true, }; } catch (error) { return { statusCode: 500, body: 'Failed to capture screenshot.', }; } finally { if (browser !== null) { await browser.close(); } } };
AWS Lambda는 alixaxel/chrome-aws-lambda
와 같은 타사 Chromium 라이브러리와 함께 puppeteer-core
를 사용해야 합니다. AWS는 Lambda 함수 크기에 250MB 제한을 부과하기 때문입니다. Puppeteer와 함께 번들로 제공되는 기본 Chromium은 이 제한을 쉽게 초과하므로(macOS에서 ~170MB, Linux에서 ~282MB, Windows에서 ~280MB) 슬림화된 Chromium을 사용해야 합니다.
로컬 개발
로컬 디버깅은 런타임 환경의 차이로 인해 복잡한 구성이 필요합니다. alixaxel/chrome-aws-lambda
의 가이드에서 확인할 수 있습니다.
배포
배포하려면 node_modules
를 ZIP 파일로 업로드해야 합니다. 사용 사례에 따라 Lambda Layers를 구성해야 할 수도 있습니다. 주요 비즈니스 로직은 AWS 콘솔에서 직접 작성하여 실행하도록 저장할 수 있습니다.
요약
✅ 장점:
- 더 간단한 코드 구조.
❌ 단점:
- 잠재적인 위험을 초래할 수 있는 타사 Chromium 라이브러리에 의존합니다.
- 복잡한 로컬 디버깅.
- ZIP 업로드 및 잠재적으로 Lambda Layers가 필요한 지루한 배포 프로세스.
Cloudflare Browser Rendering
코드 예시:
import puppeteer from '@cloudflare/puppeteer'; export default { async fetch(request, env) { const { searchParams } = new URL(request.url); let url = searchParams.get('url'); if (url) { url = new URL(url).toString(); // normalize const browser = await puppeteer.launch(env.MYBROWSER); const page = await browser.newPage(); await page.goto(url); const img = await page.screenshot(); await browser.close(); return new Response(img, { headers: { 'content-type': 'image/png', }, }); } else { return new Response('Please add an ?url=https://example.com/ parameter'); } }, };
Cloudflare Browser Rendering은 비교적 새로운 서버리스 Puppeteer 솔루션입니다. AWS Lambda와 마찬가지로 공식 Puppeteer 라이브러리를 지원하지 않습니다. 대신 Cloudflare에서 제공하는 Puppeteer 버전을 사용합니다.
Cloudflare의 라이브러리는 타사 옵션보다 더 안전하지만 업데이트 주기가 느려서 실망스러울 수 있습니다. 5개월 이상 업데이트되지 않았습니다!
또한 Cloudflare Browser Rendering에는 몇 가지 제한 사항이 있습니다.
- Worker Pro 사용자만 사용할 수 있습니다.
- 각 Cloudflare 계정은 분당 최대 2개의 브라우저만 만들 수 있으며, 동시에 실행되는 브라우저는 2개를 초과할 수 없습니다.
로컬 개발
로컬 디버깅에는 복잡한 구성이 필요합니다.
배포
배포하려면 온라인에서 함수를 작성하고 실행하도록 저장합니다.
요약
✅ 장점:
- 더 간단한 코드 구조.
❌ 단점:
- 업데이트 주기가 느린 Clouflare의 Puppeteer 라이브러리에 의존합니다.
- 복잡한 로컬 디버깅.
- 유료 장벽 및 기타 제한 사항으로 인해 액세스가 제한됩니다.
결론
이 기사에서는 Leapcell, AWS Lambda 및 Cloudflare Browser Rendering의 세 가지 주요 서버리스 Puppeteer 배포 플랫폼을 비교했습니다. 각 플랫폼에는 장단점이 있습니다.
어떤 플랫폼을 선호하시나요? 알고 있는 다른 서버리스 Puppeteer 배포 솔루션이 있나요? 댓글로 의견을 공유해 주세요!
Puppeteer 프로젝트를 온라인에 배포할 계획이라면 위에서 비교한 것처럼 Leapcell이 좋은 선택이 될 것입니다.
배포 가이드는 당사 문서를 참조하세요.