NEMOKOALA
서비스 모음ImageGenTossMeNemoDrop/ClipBoard/Terminal Shortcut Buttons
서비스 모음으로 돌아가기

Developer Brief

NemoDrop

가입 없이 파일·메모 공유

로그인 없이 파일이나 텍스트를 빠르게 공유하는 임시 공유 서비스로, 6자리 코드·링크·QR로 받는 사람이 내려받거나 복사할 수 있습니다.

서비스 열기GitHub 보기

핵심 정보

  • 다중 파일 합산 최대 5GB 업로드
  • 짧은 메모부터 큰 텍스트까지 공유
  • 만료 시간·업로드 이력(브라우저)
  • 한국어·영어 UI, ZIP 다운로드

기술 스택

Next.js 16React 19TypeScriptTailwind CSS 4SQLitePrisma 7TanStack Querynext-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으로 로깅, 용량 한도·저장 경로 등은 환경 변수로 분리

문제 · 해결

문제

다중 파일 합산 최대 5GB 업로드를 한 요청으로 받으면 전체를 메모리에 버퍼링할 수 없고, 프레임워크·프록시의 본문 크기 제한에도 걸림

해결

Busboy로 multipart를 스트리밍 파싱하고 요청 본문을 Node 스트림으로 브릿지해 각 파일을 createWriteStream으로 디스크에 직접 기록(메모리 비적재). content-length 사전 검사와 누적 바이트 실시간 검사로 한도 초과 시 즉시 413으로 차단하고, Next.js proxyClientMaxBodySize와 Nginx client_max_body_size를 6GB로 맞춰 프록시 한도까지 상향

문제

여러 파일을 한 번에 받으려면 하나의 ZIP으로 묶어야 하는데, 최대 5GB나 되는 ZIP을 서버 메모리에 통째로 만들면 메모리가 부족해 서버가 멈출 수 있음

해결

ZIP을 메모리에 완성하지 않고 스트리밍으로 처리. archiver로 압축한 결과를 곧바로 응답 스트림으로 흘려보내고(PassThrough → Readable.toWeb), 각 파일도 통째로 읽지 않고 ReadStream으로 하나씩 이어 붙여, 5GB급도 메모리에 올리지 않고 다운로드를 제공

문제

로그인이 없어 공유 항목이 무한정 쌓여 디스크·DB가 비대해지고, 만료된 파일이 계속 접근 가능하면 안 됨

해결

세션마다 만료 시각을 두고 다운로드 시 만료를 검사해 410으로 차단하며, instrumentation의 node-cron으로 매시간 만료 세션의 파일 디렉터리와 DB 레코드를 함께 삭제해 자동 정리

문제

기억하기 쉬운 6자리 코드는 충돌 가능성이 있고, 과거에 만료된 코드가 새 업로드를 막아서는 안 됨

해결

코드 유니크 검사를 '만료되지 않은 세션'으로 한정(최대 10회 재시도)해 활성 코드 충돌만 회피하고, 만료된 코드는 자연스럽게 재사용 가능하도록 처리

스크린샷

메인 화면
메인 화면
파일 업로드
파일 업로드
공유 코드·QR
공유 코드·QR
다운로드
다운로드

다른 서비스

ImageGenAI 이미지 생성·공유TossMe토스로 바로 송금Terminal Shortcut Buttons커서·VS Code 터미널 버튼ClipBoard클립보드 히스토리 매니저