-
[NestJS] EC2에서 Puppetter를 활용한 PDF 파일 다운로드공부/Nest 2025. 10. 25. 15:09
PDF 파일을 다운 받을 수 있도록 구현해야 하는 업무가 있었습니다.
구현하면서 겪었던 내용을 공유하려고 글을 작성하였습니다.
혹시라도 부정확한 정보를 전달드릴 수 있습니다. 다만 틀린 부분이 있으면 댓글을 남겨주세요.
Puppeteer란?
Puppeteer는 Google Chrome 팀에서 개발한 Node.js 라이브러리로, 웹 페이지를 렌더링 하고 PDF로 변환하는 작업에 매우 적합합니다.
1. 로컬에서 Puppetter 라이브러리 설치
npm i puppeteer2. 코드 구현
// service.ts // PDF에 출력되는 page를 HTML로 구현하였습니다. const htmlContent = template.generateHtmlTemplate(); const browser = await puppeteer.launch({ headless: true, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--single-process', // 단일 프로세스 모드로 실행하여 리소스 사용 최적화 ], timeout: 30000, // 브라우저 실행 타임아웃 설정 }); try { const date = new Date(); const defaultFileName = `PDF 생성 테스트_${date}.pdf`; const encodedFileName = encodeURIComponent(defaultFileName); // 한글 인코딩으로 PDF 파일명 지정 const page = await browser.newPage(); await page.setContent(htmlContent, { waitUntil: 'networkidle0', // 이미지나 외부에 있는 리소스가 모두 가져온 후 PDF를 생성합니다. }); const pdfBuffer = await page.pdf({ format: 'A4', printBackground: true, // CSS 배경색과 이미지를 PDF에 포함 preferCSSPageSize: true, // CSS의 @page 규칙을 우선 적용 displayHeaderFooter: false, // 기본 헤더, 푸터 비활성화 margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm', }, scale: 1, }); return { fileName: encodedFileName, pdfBuffer: Buffer.from(pdfBuffer), contentType: 'application/pdf', }; } finally { await browser.close(); // 메모리 누수를 방지하기 위한 브라우저 인스턴스 종료 }// controller.ts @Get('download') async downloadPdf(@Res() res: Response) { const { fileName, pdfBuffer, contentType } = await this.pdfService.generatePdf(); res.set({ 'Content-Type': contentType, 'Content-Disposition': `attachment; filename*=UTF-8''${fileName}`, 'Content-Length': pdfBuffer.length, }); res.end(pdfBuffer); }실제 구현한 코드의 일부분을 가져와서 수정하였습니다.

postman에서 보이는 예시입니다. 우측에 있는 ... 를 누르시면 save response to file을 누르시면 파일을 다운 받으실 수 있습니다.
3. EC2에서 사용하기
local에는 chrome이 설치된 환경이라서 문제가 없지만 EC2 인스턴스는 동일한 환경이 아니기 때문에 테스트 하시면 서버에러가 발생하게 됩니다.
EC2에서는 추가적으로 설치해줘야 하는 부분들이 존재합니다.
# Chromium 설치(ubuntu) sudo apt-get update sudo apt-get install -y chromium-browser # 필수 라이브러리 설치 필요 sudo apt-get update sudo apt-get install -y \ ca-certificates \ fonts-liberation \ libappindicator3-1 \ libasound2 \ libatk-bridge2.0-0 \ libatk1.0-0 \ libc6 \ libcairo2 \ libcups2 \ libdbus-1-3 \ libexpat1 \ libfontconfig1 \ libgbm1 \ libgcc1 \ libglib2.0-0 \ libgtk-3-0 \ libnspr4 \ libnss3 \ 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 \ lsb-release \ wget \ xdg-utils # 한글 폰트 깨짐 설정 sudo apt-get install -y \ fonts-nanum \ fonts-nanum-coding \ fonts-nanum-extra \ fonts-noto-cjk \ fonts-noto-color-emoji \ fonts-dejavu-core \ fontconfig총 3개를 설치하지만 한글 폰트 깨짐이 없으시다면 폰트 설정은 무시하셔도 됩니다.
저의 경우 한글 폰트가 깨져서 폰트 설정도 함께 해주었습니다.
이를 통해서 PDF 파일을 다운 받을 수 있도록 설정하였습니다.
실제 결과물은 회사정보를 포함하고 있어서 보여드리지 못하는 점 죄송합니다.
Ref.
https://www.npmjs.com/package/puppeteer
'공부 > Nest' 카테고리의 다른 글
ReferenceError: crypto is not defined (0) 2025.05.24 [Nest] CPU 상승 개선을 위한 Docker로 Redis 적용 (0) 2024.10.06 [Nest] TypeORM의 DELETE, REMOVE 차이 (0) 2024.06.02 [NestJS] 랜덤 문자열을 생성하여 양방향 암호화 진행하기 (0) 2024.04.23 [NestJS] 기본 구조 (0) 2023.09.09