Vercel에서 Puppeteer 배포가 실패하는 이유(및 해결 방법)
로컬 설정에서 웹 스크래핑이나 스크린샷 도구를 실행하는 것은 일반적으로 배포할 때까지 원활하게 진행됩니다. 나는 최근에 내 제품을 출시하려고 할 때 이 정확한 문제에 직면했습니다. 인형사 스크립트 켜기 베르셀. 🚀 로컬 컴퓨터에서 모든 것이 완벽하게 실행되는 동안 Vercel 배포에서 계속 오류가 반환되었습니다. "크롬(버전 130.0.6723.116)을 찾을 수 없습니다.".
이 오류는 특히 로컬 테스트 중에 표시되지 않기 때문에 실망스러울 수 있습니다. 문제는 일반적으로 배포된 환경에 브라우저 버전이 없거나 브라우저의 잘못된 구성을 가리킵니다. 캐시 경로 Puppeteer가 Vercel에서 사용하는 것입니다.
Vercel은 기본적으로 Puppeteer에 필요한 특정 Chrome 실행 파일을 항상 포함하지 않습니다. 즉, 스크립트가 런타임 중에 해당 실행 파일을 찾지 못할 수도 있습니다. 이 가이드에서는 이 오류가 발생하는 이유와 이를 해결하기 위한 몇 가지 전략을 안내합니다.
Puppeteer를 처음 접하는 개발자이거나 배포 문제를 해결하는 개발자라면 이러한 미묘한 차이를 이해하면 디버깅 시간을 절약할 수 있습니다. 🛠️ 솔루션을 자세히 살펴보고 Vercel에서 Puppeteer 설정을 원활하게 실행해 보겠습니다.
명령 | 사용예 및 상세설명 |
---|---|
puppeteer.launch({ ... }) | 이 명령은ignoreHTTPSErrors 및 실행 파일 경로와 같은 특정 구성 옵션을 사용하여 Puppeteer의 인스턴스를 시작합니다. 이러한 옵션은 Chrome 실행 파일의 정확한 위치를 설정하고 보안 설정을 관리하여 Vercel과 같은 배포 플랫폼에서 Chrome 버전의 오류를 해결하는 데 도움이 됩니다. |
executablePath | puppeteer.launch 내에서 사용되는 실행 경로는 Chrome 바이너리의 경로를 지정합니다. 이 경로를 설정하면 Puppeteer가 원격 서버에서 올바른 Chrome 버전을 사용할 수 있습니다. 이는 Chrome이 기본적으로 설치되지 않을 수 있는 Vercel과 같은 서버리스 환경에 필수적입니다. |
args: ['--no-sandbox', '--disable-setuid-sandbox'] | 이러한 플래그는 Puppeteer가 많은 클라우드 호스팅 제공업체에서 실행되는 데 필요한 Chrome의 샌드박싱 기능을 비활성화합니다. 샌드박스는 일반적으로 공유 서버의 권한 오류를 방지하기 위해 비활성화되어 있지만 보안 문제 때문에 신중하게 수행해야 합니다. |
cacheDirectory | Puppeteer의 구성 파일에서 캐시디렉토리는 브라우저 캐싱을 위한 사용자 정의 디렉터리를 설정합니다. 이는 Puppeteer가 다운로드한 Chrome 바이너리를 저장하는 위치를 제어하여 캐시 관련 오류를 방지할 수 있으므로 Vercel에서 특히 유용합니다. |
await page.goto(url, { waitUntil: 'networkidle2' }) | 이 명령은 URL을 로드하고 페이지가 완전히 로드된 것으로 간주될 네트워크 연결이 2개 이하가 될 때까지 기다립니다. networkidle2 옵션은 스크린샷을 찍기 전에 모든 리소스가 로드되었는지 확인하므로 복잡한 페이지를 캡처하는 데 이상적입니다. |
page.setViewport({ width: 1920, height: 1080 }) | 지정된 크기의 화면을 시뮬레이션하여 Chrome 인스턴스의 뷰포트 크기를 설정합니다. 이는 캡처된 웹페이지의 모양을 제어하므로 스크린샷 및 시각적 테스트에 필수적입니다. |
path.join(__dirname, '..', 'public', fileName) | 이 명령은 현재 디렉터리를 공용 폴더와 결합하여 스크린샷을 저장할 특정 디렉터리를 생성하여 파일 경로를 구성합니다. 특히 스크린샷 경로를 클라이언트에 다시 제공할 때 출력 파일을 구성하는 데 필수적입니다. |
uuid() | 각 스크린샷에 대한 고유 식별자를 생성하여 각 파일 이름이 고유하고 덮어쓰기를 방지합니다. 이 기능은 여러 이미지나 데이터 파일을 동시에 저장하는 애플리케이션에 특히 유용합니다. |
chai.request(app) | Chai HTTP 모듈의 일부인 이 명령은 엔드포인트 응답을 테스트하기 위해 애플리케이션 서버(앱으로 정의됨)에 요청을 보냅니다. 이는 개발자가 스크린샷 API가 예상대로 작동하는지 확인할 수 있도록 자동화된 테스트에 유용합니다. |
describe() and it() | 이러한 Mocha 테스트 함수는 기능 검증을 위한 테스트 모음(describe()) 및 개별 테스트(it())를 정의합니다. 매개변수 누락부터 유효한 URL까지 다양한 조건에서 Puppeteer 스크린샷 API의 각 측면이 올바르게 작동하는지 확인하는 데 사용됩니다. |
Vercel 배포 시 Puppeteer의 Chrome 오류 극복
제공된 기본 스크립트는 다음을 사용하는 백엔드 기능입니다. 인형사 사용자가 제공한 URL의 스크린샷을 캡처합니다. 이 작업은 미리보기를 동적으로 생성하거나 웹 스크래핑 목적으로 특히 유용합니다. 그러나 다음과 같은 플랫폼에 배포하는 것은 베르셀 환경에서 Chrome을 찾을 수 없는 등의 오류가 발생할 수 있습니다. 이는 Vercel이 예상 위치에 Chrome이 사전 설치되어 있지 않기 때문에 발생합니다. 즉, 올바른 버전을 찾거나 설치하도록 Puppeteer를 구성해야 합니다. 이 예에서는 맞춤 Chrome 바이너리에 대한 Puppeteer의 실행 경로를 지정하고 설정이 환경 전반에서 작동하는지 확인하기 위해 IgnoreHTTPSErrors 플래그로 SSL 문제를 처리하는 옵션을 구현했습니다.
스크립트는 요청에서 URL을 가져오는 스크린샷 함수를 정의하는 것으로 시작됩니다. URL이 누락된 경우 JSON 오류 응답을 다시 보내지만, 제공된 경우 다음과 같은 필수 구성으로 Puppeteer를 초기화합니다. 실행 파일 경로 그리고 인수 옵션. 그만큼 실행 파일 경로 이는 Puppeteer를 정확한 Chrome 위치로 안내하여 Vercel의 'Chrome을 찾을 수 없음' 오류를 해결하기 때문에 여기서 필수적입니다. 추가적으로, 인수 옵션, 구체적으로 샌드박스 없음 그리고 비활성화-setuid-샌드박스, 특정 서버리스 환경의 요구 사항인 Chrome의 샌드박싱 기능을 비활성화합니다. 이러한 설정을 통해 Vercel의 관리형 인프라에 대한 권한 문제 없이 스크립트를 실행할 수 있습니다.
Puppeteer가 시작되면 스크립트는 새 브라우저 페이지를 열고 다음을 사용합니다. 고토 와 함께 네트워크 유휴 2 옵션. 이는 Puppeteer에게 페이지가 완전히 로드될 때까지 기다리도록 지시하며, 진행 중인 네트워크 요청은 2개 이하이므로 복잡한 페이지라도 스크린샷을 찍기 전에 완전히 렌더링되도록 할 수 있습니다. 이 단계는 특히 비동기 로딩에 크게 의존하는 최신 웹 페이지를 처리할 때 안정적이고 정확한 스크린샷을 캡처하는 데 중요합니다. 그런 다음 뷰포트 크기가 1920x1080으로 설정되어 풀 HD 화면을 시뮬레이션합니다. 이는 캡처된 콘텐츠가 대부분의 사용자가 데스크톱 장치에서 볼 수 있는 레이아웃을 반영하도록 보장합니다.
마지막으로 스크립트는 다음을 사용하여 고유한 파일 이름을 생성합니다. uuid 라이브러리, 액세스할 수 있고 JSON 응답으로 사용자에게 반환될 수 있는 공개 디렉터리에 스크린샷을 저장합니다. Node를 사용하여 파일 경로를 신중하게 구성함으로써 경로.조인 방법을 사용하면 스크립트는 환경 설정의 차이로 인해 발생할 수 있는 파일 경로 문제를 방지합니다. 예를 들어 이 구조는 로컬 시스템에서 원활하게 실행되지만 Vercel에서는 동일한 경로가 작동하지 않을 수 있으므로 각 파일 경로를 모듈식 및 적응 가능한 방식으로 정의하는 것이 중요합니다. 궁극적으로 이 설정은 Puppeteer 기능이 로컬 및 서버리스 환경 모두에서 원활하게 작동하여 페이지 로딩, 오류 처리 및 환경 제약 조건과 같은 모든 주요 측면을 처리하도록 보장합니다. 🖥️
해결 방법 1: Vercel에 Chrome을 올바르게 설치하도록 Puppeteer 구성
이 Node.js 기반 백엔드 솔루션은 Chrome이 올바르게 설치되도록 Puppeteer의 캐시 경로와 설치 명령을 구성합니다.
const puppeteer = require('puppeteer');
const path = require('path');
const { v4: uuid } = require('uuid');
const fs = require('fs');
// Main screenshot function
const screenshot = async (req, res) => {
const url = req.query.url;
if (!url) {
return res.status(400).json({ message: 'URL is required' });
}
let browser;
try {
// Launch Puppeteer with specific Chrome executable path and options
browser = await puppeteer.launch({
ignoreHTTPSErrors: true,
executablePath: process.env.CHROME_PATH || '/opt/bin/chromium',
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
await page.setViewport({ width: 1920, height: 1080 });
const fileName = \`${uuid()}.png\`;
const screenshotPath = path.join(__dirname, '..', 'public', fileName);
await page.screenshot({ path: screenshotPath });
res.json({ screenshotPath: \`/image/\${fileName}\` });
} catch (err) {
console.error('Error capturing screenshot:', err);
res.status(500).json({ error: 'Failed to capture screenshot' });
} finally {
if (browser) await browser.close();
}
};
module.exports = screenshot;
솔루션 2: .puppeteerrc.cjs 파일을 사용한 Vercel용 사용자 정의 Puppeteer 구성
이 솔루션은 Puppeteer의 구성 파일(.puppeteerrc.cjs)을 조정하여 Chrome 캐시 경로를 지정하고 Vercel의 파일 구조와의 호환성을 보장합니다.
const { join } = require('path');
/
* @type {import('puppeteer').Configuration}
*/
module.exports = {
// Specify cache directory for Puppeteer
cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
// Specify which Chromium version Puppeteer should install
executablePath: '/opt/bin/chromium',
args: ['--no-sandbox', '--disable-setuid-sandbox'],
};
해결 방법 3: Puppeteer용 package.json에 환경 변수 및 스크립트 구현
이 접근 방식은 패키지.json 특정 Chrome 바이너리를 설치하고 배포 중에 Puppeteer 구성을 자동으로 설정하는 파일입니다.
// Add to package.json
"scripts": {
"postinstall": "npx puppeteer install --path ./.cache/puppeteer",
"start": "node index.js"
}
// Configure environment variable in Vercel
process.env.CHROME_PATH = "/opt/bin/chromium";
Puppeteer 스크린샷 기능에 대한 단위 테스트
이 Node.js Mocha 테스트 스크립트는 다양한 환경에서 URL의 스크린샷을 캡처하는 Puppeteer의 기능을 확인합니다.
const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../app'); // Express app where screenshot endpoint is defined
chai.use(chaiHttp);
const expect = chai.expect;
describe('Screenshot API', () => {
it('should return an error for missing URL parameter', (done) => {
chai.request(app)
.get('/screenshot')
.end((err, res) => {
expect(res).to.have.status(400);
expect(res.body).to.have.property('message').eql('URL is required');
done();
});
});
it('should capture a screenshot successfully for a valid URL', (done) => {
chai.request(app)
.get('/screenshot?url=https://example.com')
.end((err, res) => {
expect(res).to.have.status(200);
expect(res.body).to.have.property('screenshotPath');
done();
});
});
});
클라우드 환경에 맞게 Puppeteer 최적화
Puppeteer 기반 애플리케이션을 다음과 같은 클라우드 플랫폼에 배포하는 경우 베르셀 또는 Heroku, 이러한 환경의 한계를 이해하는 것이 필수적입니다. 로컬 설정과 달리 클라우드 환경은 일반적으로 관리형 또는 서버리스 아키텍처에서 작동합니다. 즉, Chrome과 같은 종속성을 항상 쉽게 사용할 수 있는 것은 아닙니다. 사실 퍼피티어의 launch 필요한 Chrome 버전이 서버에 설치되어 있지 않으면 메서드가 실패하여 'Chrome을 찾을 수 없습니다.'와 같은 오류가 발생할 수 있습니다. 좋은 방법은 다음을 사용하여 Chrome의 실행 파일 경로를 지정하는 것입니다. executablePath, 이를 통해 Puppeteer는 모든 환경에서 Chrome을 효과적으로 찾고 실행할 수 있습니다.
이 외에도 필요한 시작 인수를 추가하는 것은 호환성을 위해 중요합니다. 다음과 같은 플래그 --no-sandbox 그리고 --disable-setuid-sandbox 특히 도움이 됩니다. 이러한 플래그는 Chrome의 일부 보안 기능을 비활성화하지만 Chrome의 샌드박스가 지원되지 않는 서버리스 설정에는 필요한 경우가 많습니다. 또한 Puppeteer를 사용하여 사용자 정의 캐시 디렉토리를 지정합니다. cacheDirectory 옵션은 특히 여러 브라우저 버전이 관련된 경우 잠재적인 캐시 문제를 방지하는 데 도움이 됩니다. 예를 들어, 설정 cacheDirectory 알려진 디렉터리에 추가하면 런타임 중에 모든 종속성을 사용할 수 있습니다.
마지막으로, 최적화 goto 방법을 사용하면 성능이 크게 향상될 수 있습니다. 을 사용하여 waitUntil: 'networkidle2' 옵션을 선택하면 스크립트는 페이지 로드가 완료될 때까지 기다립니다. 이는 인터넷 속도나 리소스 로드가 다양해지는 환경에서 중요합니다. 이는 콘텐츠가 비동기적으로 로드되는 동적 페이지나 애플리케이션에서 정확한 스크린샷을 캡처하는 데 특히 유용합니다. 이러한 기술의 조합을 통해 Puppeteer는 클라우드 플랫폼에서 원활하게 작동하여 프로덕션에서 자동화된 작업을 위한 강력한 솔루션을 제공합니다. 🚀
Puppeteer 및 클라우드 배포에 대한 일반적인 질문
- 클라우드 플랫폼에서 'Chrome을 찾을 수 없습니다' 오류가 발생하는 이유는 무엇입니까?
- 이러한 오류는 클라우드 플랫폼이 기본적으로 전체 Chrome 바이너리를 포함하지 않기 때문에 자주 발생합니다. 다음을 지정하여 이 문제를 해결할 수 있습니다. executablePath Puppeteer 설정에서.
- Puppeteer가 로컬 및 클라우드 환경 모두에서 작동하는지 어떻게 확인합니까?
- 사용 executablePath 그리고 args 다음과 같은 클라우드 친화적인 플래그를 사용하여 --no-sandbox 두 환경 모두에 맞게 설정을 유연하게 만들 수 있습니다.
- 무엇을 하는가? --no-sandbox Puppeteer에 플래그를 지정하나요?
- 그만큼 --no-sandbox 플래그는 Chrome의 샌드박스 보안을 비활성화하여 Puppeteer가 샌드박싱을 지원하지 않는 클라우드 서비스에서 실행될 수 있도록 허용하지만 주의해서 사용해야 합니다.
- 왜 맞춤이 필요한가요? cacheDirectory 인형사를 위해?
- 사용자 정의 설정 cacheDirectory Puppeteer는 Chrome 바이너리를 알려진 위치에 다운로드하므로 특히 서버리스 환경에서 배포 중 오류를 방지할 수 있습니다.
- 의 목적은 무엇입니까? networkidle2 옵션 goto 방법?
- 그만큼 networkidle2 옵션은 활성 네트워크 연결이 2개 이하가 될 때까지 기다립니다. 이는 완전히 로드된 페이지를 캡처하고 동적 콘텐츠를 처리하는 데 유용합니다.
- Puppeteer는 지정된 Chrome 버전 없이 작동할 수 있나요?
- 예, 하지만 지정하는 것이 좋습니다 executablePath 클라우드 설정에서 일관된 결과를 얻으려면 호환되는 Chrome 버전에 액세스할 수 있는지 확인하세요.
- 다양한 환경에서 Puppeteer 캐시를 어떻게 관리합니까?
- 범용을 지정할 수 있습니다. cacheDirectory 에서 .puppeteerrc.cjs 파일을 사용하면 Puppeteer가 Vercel 및 Heroku와 같은 플랫폼에서 Chrome 바이너리를 찾을 수 있습니다.
- ~이다 puppeteer-core 와는 다르다 puppeteer?
- 예, puppeteer-core 크기를 줄이기 위해 번들로 제공되는 Chrome을 제외하므로 Chrome 바이너리를 지정해야 합니다. 전체 puppeteer 패키지에는 Chrome이 자동으로 포함됩니다.
- 클라우드 환경에서 Puppeteer가 느려지면 어떻게 해야 하나요?
- 최적화 viewport 설정 및 다음과 같은 불필요한 옵션을 비활성화합니다. devtools 리소스가 제한된 환경에서 성능을 향상시킬 수 있습니다.
- Puppeteer는 모든 클라우드 제공업체와 호환됩니까?
- 일반적으로 그렇습니다. 그러나 각 제공업체마다 고유한 요구 사항이 있을 수 있습니다. 다음과 같은 클라우드 친화적인 설정 사용 --no-sandbox 더 나은 호환성을 보장합니다.
Vercel에서 Puppeteer를 실행하는 것에 대한 최종 생각
Vercel에 Puppeteer를 성공적으로 배포하려면 Chrome의 특정 설정 요구 사항을 이해해야 합니다. 지정 실행 옵션 Puppeteer의 캐시 경로를 올바르게 구성하면 실망스러운 'Chrome을 찾을 수 없습니다' 오류를 방지하는 데 도움이 됩니다. 이러한 조정을 통해 Puppeteer는 로컬 및 클라우드 환경 모두에서 안정적으로 작동합니다. 🚀
이러한 솔루션을 프로젝트에 적용하면 사용자가 제공한 URL에서 스크린샷 캡처가 원활해지면서 보다 동적인 웹 애플리케이션이 가능해집니다. 적절한 설정을 통해 Puppeteer는 Vercel과 같은 서버리스 플랫폼에서도 자동화 및 웹 스크래핑을 위한 귀중한 도구로 남아 있습니다.
Puppeteer 오류 문제 해결을 위한 소스 및 참조
- 이 문서에서는 특히 Chrome 캐시 경로 처리 및 실행 파일 경로 지정에 대한 자세한 설정 옵션 및 문제 해결 단계에 대해 공식 Puppeteer 구성 가이드를 참조합니다. 인형사 구성 가이드
- Vercel 문서는 서버리스 환경이 종속성을 처리하는 방법과 헤드리스 브라우저에 의존하는 애플리케이션을 배포하기 위한 고유한 요구 사항에 대한 통찰력을 제공합니다. Vercel 문서
- 스택 오버플로 토론에서는 배포 중에 발생하는 특정 Puppeteer 및 Chrome 문제를 다루는 커뮤니티 중심 솔루션과 오류 처리의 실제 예를 제공합니다. 스택 오버플로