Puppeteer 온라인 실행 최선의 방법: 솔루션 비교
Takashi Yamamoto
Infrastructure Engineer · Leapcell

웹사이트 스크린샷 찍기, PDF 생성, 자동화 테스트, 웹사이트 스크래핑, 웹 콘텐츠 변경 사항 모니터링 등이 있습니다.
많은 경우 Puppeteer를 온라인에서 실행해야 합니다. 예를 들어:
- CI/CD 파이프라인에서 온라인 Puppeteer를 호출하여 자동화된 테스트를 실행합니다.
- cron을 사용하여 웹사이트 가용성을 정기적으로 확인합니다.
- 대규모, 분산 웹 크롤러를 실행합니다.
Puppeteer 작업은 일반적으로 수명이 짧고 지속적으로 트리거되지 않기 때문에 전체 서버(예: DigitalOcean)에 호스팅하는 것은 비용 효율적이지 않습니다. Puppeteer가 실행 중인지 여부에 관계없이 서버는 모든 순간에 청구되기 때문입니다.
이상적인 접근 방식은 서버리스 모델을 사용하여 Puppeteer를 배포하는 것입니다. 서버리스 서비스는 실제 호출에 따라 요금을 부과하므로 다양한 시나리오에서 일반적으로 훨씬 저렴합니다.
현재 몇 안 되는 플랫폼만이 서버리스 방식으로 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 a ?url=https://example.com/ parameter'); } }); const port = 8080; serve({ fetch: app.fetch, port }).on('listening', () => { console.log(`Server is running on port ${port}`); });
Leapcell은 다양한 언어로 배포를 지원하므로 이 요구 사항은 쉽게 충족됩니다.
로컬 개발 및 디버깅
로컬 디버깅은 매우 간단합니다. 다른 Node.js 애플리케이션과 마찬가지입니다: node index.js
를 실행하면 됩니다!
배포
배포하려면 빌드 명령, 실행 명령 및 서비스 포트를 지정해야 합니다(아래 스크린샷 참조).
구체적인 배포 매개변수 및 절차는 공식 설명서에 자세히 나와 있습니다.
배포 후 애플리케이션을 온라인으로 사용할 수 있습니다.
요약
✅ 장점:
- 일관된 로컬 및 클라우드 환경으로 디버깅이 더 쉽습니다.
- 공식 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는 puppeteer-core
와 함께 alixaxel/chrome-aws-lambda와 같은 타사 Chromium 라이브러리를 사용해야 합니다.
이는 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 a ?url=https://example.com/ parameter'); } }, };
Cloudflare Browser Rendering은 비교적 새로운 서버리스 Puppeteer 솔루션입니다. AWS Lambda와 유사하게 공식 Puppeteer 라이브러리를 지원하지 않습니다. 대신 Cloudflare에서 제공하는 Puppeteer 버전을 사용합니다.
Cloudflare의 라이브러리는 모든 타사 옵션보다 안전하지만, 예를 들어 5개월 이상 업데이트되지 않은 적이 있는 등 느린 업데이트 주기로 인해 답답함을 느낄 수 있습니다!
또한 Cloudflare Browser Rendering에는 몇 가지 제한 사항이 있습니다:
- Worker Pro 사용자에게만 제공됩니다.
- 각 Cloudflare 계정은 분당 최대 2개의 브라우저를 생성할 수 있으며, 동시에 최대 2개의 브라우저만 실행할 수 있습니다.
로컬 개발 및 디버깅
로컬 디버깅에는 복잡한 구성이 필요합니다.
배포
배포하려면 온라인에서 함수를 작성하고 저장한 다음 실행하기만 하면 됩니다.
요약
✅ 장점:
- 구현 코드가 비교적 간단합니다.
❌ 단점:
- 불안정한 업데이트 주기를 가진 Cloudflare의 Puppeteer 라이브러리에 의존합니다.
- 복잡한 로컬 디버깅.
- 유연한 사용을 방해하는 유료 장벽 및 기타 제한 사항이 있습니다.
결론
이 기사에서는 Leapcell, AWS Lambda 및 Cloudflare Browser Rendering의 세 가지 주요 서버리스 플랫폼을 비교하여 Puppeteer를 배포했습니다. 각 플랫폼에는 고유한 장단점이 있습니다.
그러나 모든 것을 고려할 때 Puppeteer 프로젝트를 온라인으로 배포할 계획이라면 Leapcell은 훌륭한 선택입니다.