프로젝트 소개
GitHub : https://github.com/leey00nsu/leemage
Demo : https://leemage.leey00nsu.com/
사이드 프로젝트에 파일 업로드 기능을 추가할 때 비용 문제가 발생했습니다.
OCI Object Storage / Cloudflare R2는 Free Tier로 일정 용량을 무료로 제공하기 때문에, Cloudinary 같은 유료 서비스 대신 비용 절감을 위한 자체 호스팅 파일 관리 플랫폼을 구축했습니다.
프로젝트 단위로 파일을 정리하고, 외부 API와 SDK를 통해 다른 프로젝트에 빠르게 통합할 수 있습니다.
핵심 기능
- 프로젝트 단위 파일 업로드/관리: 이미지·비디오·문서 등 모든 확장자 지원
- 이미지 변환 옵션 제공: 리사이즈/포맷 변환
- 외부 API/SDK 제공: RESTful API 및 TypeScript SDK 제공
- OpenAPI 문서 자동화: Zod 스키마에서 OpenAPI 스펙 자동 생성
- 멀티 스토리지 지원: OCI Object Storage / Cloudflare R2 선택 가능
- i18n 지원: 한국어/영어 제공
Problem
- 대용량 파일 업로드 시 서버 부하: 파일이 서버를 거치면 메모리/네트워크 부하 급증
- 멀티 스토리지 API 차이: OCI Object Storage와 Cloudflare R2는 API 인터페이스가 상이하여 프로바이더 변경 시 코드 전체 수정 부담
- 이미지 용량 최적화: 무거운 이미지 리사이징/포맷 변환 필요
- API 문서 불일치: API 문서를 별도 관리할 경우 코드와 문서 간 불일치 발생 가능
Solution
- Presigned URL 직접 업로드: 클라이언트가 스토리지에 직접 업로드하여 서버 부하 제거
- Storage Adapter 패턴: 공통 인터페이스로 프로바이더 독립적인 코드 작성, 새 프로바이더 추가 시 어댑터만 구현 (OCP 준수)
- Sharp 기반 이미지 변환: 병렬 처리로 여러 variant 동시 생성, WebP/AVIF의 가벼운 차세대 포맷 지원
- TypeScript SDK: 복잡한 3단계 업로드 플로우(presign → upload → confirm)를 단일 메서드로 추상화
- OpenAPI 자동 생성: Zod 스키마에서 OpenAPI 스펙 자동 생성으로 API 문서와 타입 동기화
Impact
- 서버 부하: Presigned URL로 파일 전송 서버 부하 0%
- 이미지 용량 최적화: WebP/AVIF 변환으로 원본 대비 50-60% 감소
- 비용 절감: OCI, Cloudflare R2 Free Tier 활용
- 통합 용이성: TypeScript SDK로 외부 프로젝트에 빠른 통합 가능
기술 스택
- Frontend: Next.js, TypeScript, Tailwind CSS
- Data/Validation: TanStack Query, Zod
- Backend/DB: Next.js API Routes, Prisma, PostgreSQL
- Image: Sharp
- Infra: OCI Object Storage, Cloudflare R2
