
개요
로그인 없이 파일이나 텍스트를 빠르게 공유하는 임시 공유 서비스로, 6자리 코드·링크·QR로 받는 사람이 내려받거나 복사할 수 있습니다.
주요 기능
- 다중 파일 합산 최대 5GB 업로드
- 짧은 메모부터 큰 텍스트까지 공유
- 만료 시간·업로드 이력(브라우저)
- 한국어·영어 UI, ZIP 다운로드
기술 스택
- Next.js 16
- React 19
- TypeScript
- Tailwind CSS 4
- SQLite
- Prisma 7
- TanStack Query
- next-intl
아키텍처
로그인 없이 대용량 파일과 텍스트를 빠르게 공유하는 데 초점을 맞춰, 데이터를 메모리에 적재하지 않는 스트리밍 파이프라인과 만료 기반 자동 정리를 중심으로 설계했습니다.
Application
- Next.js 16 App Router 기반, /[locale] 경로와 next-intl 미들웨어로 한국어·영어 다국어 라우팅
- 업로드·텍스트·단일/전체 다운로드·세션 조회를 Route Handler(API Route)로 구현, 서버 상태는 TanStack Query로 관리
- Prisma 7 + better-sqlite3 어댑터로 SQLite 연동, Session·File 스키마를 Cascade 삭제로 묶어 관리
Streaming I/O
- 업로드는 Busboy로 multipart를 스트리밍 파싱하고, 요청 본문(Web ReadableStream)을 Node 스트림으로 브릿지해 파일을 메모리에 모으지 않고 디스크에 직접 기록
- 파일은 UPLOAD_DIR 아래 세션 코드 폴더에 UUID 이름으로 저장하고, 원본명·크기(BigInt)·MIME 타입은 DB에 분리 보관
- 단일 파일은 ReadStream으로, 다중 파일은 archiver ZIP을 PassThrough에 파이프해 스트리밍 응답 — 양쪽 모두 전체를 메모리에 적재하지 않고 전송
Lifecycle & Cleanup
- 6자리 숫자 공유 코드를 생성하되 만료되지 않은 세션만 대상으로 유니크 검사(최대 10회 재시도)해 활성 코드 충돌만 회피
- 세션마다 만료 시각(expiresAt)을 두고 다운로드 시 만료를 검사해 410으로 차단
- instrumentation register()에서 node-cron으로 매시간 만료된 세션의 파일 디렉터리와 DB 레코드를 함께 정리
Deploy & Ops
- Windows 미니 PC의 WSL에서 Next.js 프로덕션 서버(3001)를 실행하고 Nginx 리버스 프록시로 외부 요청을 받아 SSL 처리
- 업로드 한도(5GB)에 맞춰 Nginx client_max_body_size와 Next.js proxyClientMaxBodySize를 6GB로 상향
- 프로덕션 업로드·다운로드 이벤트는 Discord Webhook으로 로깅, 용량 한도·저장 경로 등은 환경 변수로 분리
문제 · 해결
- 01
다중 파일 합산 최대 5GB 업로드를 한 요청으로 받으면 전체를 메모리에 버퍼링할 수 없고, 프레임워크·프록시의 본문 크기 제한에도 걸림
Busboy로 multipart를 스트리밍 파싱하고 요청 본문을 Node 스트림으로 브릿지해 각 파일을 createWriteStream으로 디스크에 직접 기록(메모리 비적재). content-length 사전 검사와 누적 바이트 실시간 검사로 한도 초과 시 즉시 413으로 차단하고, Next.js proxyClientMaxBodySize와 Nginx client_max_body_size를 6GB로 맞춰 프록시 한도까지 상향
- 02
여러 파일을 한 번에 받으려면 하나의 ZIP으로 묶어야 하는데, 최대 5GB나 되는 ZIP을 서버 메모리에 통째로 만들면 메모리가 부족해 서버가 멈출 수 있음
ZIP을 메모리에 완성하지 않고 스트리밍으로 처리. archiver로 압축한 결과를 곧바로 응답 스트림으로 흘려보내고(PassThrough → Readable.toWeb), 각 파일도 통째로 읽지 않고 ReadStream으로 하나씩 이어 붙여, 5GB급도 메모리에 올리지 않고 다운로드를 제공
- 03
로그인이 없어 공유 항목이 무한정 쌓여 디스크·DB가 비대해지고, 만료된 파일이 계속 접근 가능하면 안 됨
세션마다 만료 시각을 두고 다운로드 시 만료를 검사해 410으로 차단하며, instrumentation의 node-cron으로 매시간 만료 세션의 파일 디렉터리와 DB 레코드를 함께 삭제해 자동 정리
- 04
기억하기 쉬운 6자리 코드는 충돌 가능성이 있고, 과거에 만료된 코드가 새 업로드를 막아서는 안 됨
코드 유니크 검사를 '만료되지 않은 세션'으로 한정(최대 10회 재시도)해 활성 코드 충돌만 회피하고, 만료된 코드는 자연스럽게 재사용 가능하도록 처리
스크린샷
1 / 4메인 화면


