Render에서 VitePress 빌드가 갑자기 죽었다 — puppeteer가 devDependencies에 박혀있었던 이야기

docs 사이트(docs.1pass.dev, VitePress) 배포가 갑자기 실패했다. Render 대시보드에는 “Exited with status 1 while building your code.” 한 줄만 떴다. 수동으로 “Clear build cache & deploy” 한 번 누르니 그대로 살아났다. 그런데 코드 자체는 한 줄도 안 바뀌었으니 찜찜했다. 무엇이 진짜 문제였는지 확인하고 가야 다음에 같은 상황에서 헤매지 않는다. 증상 Render static site (pnpm install --frozen-lockfile && pnpm run build) 새 커밋 push → 자동 빌드 시작 → 30초 만에 build_failed ...

2026-05-14 00:00 · 3분 소요 · Seunghan

JANDI 채팅방 크롤링 — AngularJS 가상 스크롤 SPA를 Puppeteer로 전수 수집한 삽질기

왜 JANDI 채팅방을 크롤링해야 했나 한국거래소(KRX)에서 증권사 담당자들과 소통하는 채널로 JANDI 메신저를 사용하고 있다. “[KRX] 거래시간 연장 및 장애대응 실시간 채팅"이라는 채팅방에서 400여 명의 증권사 담당자들이 질문하고, KRX 측이 답변하는 구조다. 문제는 이 Q&A 내역을 체계적으로 관리할 방법이 없다는 것이었다. JANDI에는 메시지 읽기 API가 없고, Outgoing Webhook은 시작 키워드가 필수라서 모든 메시지를 수신할 수 없다. 결국 브라우저 자동화로 직접 크롤링하는 수밖에 없었다. JANDI의 기술 스택이 만든 함정 JANDI 웹앱은 AngularJS 기반 SPA(Single Page Application)다. 열어보면 URL이 https://next-it.jandi.com/app/#!/room/34791415 같은 해시 라우팅을 쓰고 있다. 이게 크롤링에 어떤 영향을 주는지 처음엔 몰랐다. ...

2026-03-31 00:00 · 7분 소요 · Seunghan

앱스토어 마케팅 스크린샷 자동화 — Puppeteer + features.json 분석 주도 파이프라인

앱 출시를 앞두고 스토어 스크린샷을 만들어야 하는 상황이 됐다. Figma로 하나씩 만드는 건 너무 비효율적이고, 10가지 디자인 시안에 5개 기능 화면을 조합하면 50장인데 수작업으로 한다는 건 말이 안 된다. 그래서 HTML/CSS로 마케팅 프레임을 만들고 Puppeteer로 PNG를 뽑아내는 파이프라인을 짰다. 처음엔 대충 만들었다가 구조적으로 틀린 부분이 있다는 걸 나중에 깨달았는데, 그 과정이 의외로 중요한 교훈을 남겼다. 처음 접근 방식의 문제 처음엔 이런 식으로 기능 배열을 하드코딩했다. const FEATURES = [ { id: 'expense', title: '지출을 한번에', sub: 'AI가 영수증을 읽어드립니다', screen: '02_expense_detail' }, { id: 'camera', title: '사진 찍으면 끝', sub: 'OCR로 즉시 기록', screen: '03_camera_hub' }, // ... ]; 문제는 이 파일명들(02_expense_detail.png, 03_camera_hub.png)이 실제로 존재하지 않았다는 것이다. 캡처 스크립트가 자동으로 화면을 이동하다가 실패해서 홈 화면만 5번 찍혔는데, 파일명은 다 달랐다. 결과적으로 모든 슬롯이 placeholder(검은 화면)였다. ...

2026-03-26 00:00 · 6분 소요 · Seunghan
개인정보처리방침 이용약관 면책조항 문의