처음엔 저도 당연히 클라우드가 정답인 줄 알았습니다.
Vultr 계정에 잔액이 좀 남아있길래, 가장 저렴한 $6짜리 VPS 인스턴스를 하나 띄워 Next.js를 올리고 DB는 **Supabase Cloud(Free, 서울 리전)**를 연결했습니다. "같은 서울이니까 빠르겠지?"라고 생각했죠.
하지만 현실은 미묘하게 달랐습니다:
CPU 병목: $6짜리 VPS의 빈약한 vCPU는 Next.js의 SSR 렌더링만으로도 숨이 찼습니다. 여기에 외부 HTTPS 통신(DB 연결) 오버헤드까지 더해지니 반응이 굼떴습니다.
데이터센터 간 지연: Vultr와 Supabase(AWS)가 물리적으로는 같은 서울에 있지만, 서로 다른 통신망을 타기 때문에 **"외부 인터넷"**을 거쳐야 합니다.
"아, 답답해서 못 쓰겠다!"
결국 눈길을 돌린 건 책상 위에서 조용히 먼지만 쌓여가던 미니 PC, TOPFEEL T1이었습니다.
▲ 나의 새로운 홈 서버: TOPFEEL T1 (작다고 무시하면 다칩니다)
이 녀석의 스펙을 기존에 쓰던 $6짜리 Vultr 인스턴스와 비교해보니, 이건 "다윗과 골리앗" 싸움도 아닌 "개미와 티라노사우루스" 수준의 체급 차이가 났습니다.
**구분**
**Vultr Cloud (High Frequency)**
**TOPFEEL T1 (Home Server)**
**비고**
**CPU**
1 vCPU (Intel)
**AMD Ryzen 7 8745HS (8C/16T)**
1코어 vs 16스레드
**RAM**
1 GB
**32 GB DDR5**
대역폭과 용량 모두 압승
**Storage**
32 GB NVMe
**2TB NVMe (PCIe 4.0)**
용량 64배 차이
**Cost**
**$6.00/월** (약 8,500원)
**전기세 약 4,000원 ~ 5000원/월**
성능이 뛰어남에도 비용이 더 저렴
⚡ 퍼포먼스: "같은 서울"이어도 로컬이 더 빠른 이유
Supabase 서울 리전을 쓰면 핑(Ping)은 3~5ms 내외로 매우 빠릅니다. 하지만 **"빠른 것"**과 **"즉각적인 것(Instant)"**의 차이는 큽니다.
클라우드 환경에서는 쿼리 하나를 날릴 때마다 Next.js(Vultr) ↔ 인터넷망 ↔ Supabase(AWS) 과정을 거치며 SSL 핸드쉐이크와 네트워크 홉이 발생합니다. 하지만 셀프 호스팅은 이 모든 과정이 생략됩니다.
**비교 항목**
**Supabase Cloud (서울)**
**Self-Hosted (로컬)**
**차이점**
**통신 경로**
Vultr ↔ Public Internet ↔ AWS
**Docker Bridge Network**
외부망 vs 내부망
**지연 시간 (RTT)**
2ms ~ 10ms (가변적)
**< 0.1ms (마이크로초)**
**비교 불가**
**안정성**
인터넷 회선 상태 영향 받음
**네트워크 변수 0%**
💡 핵심: 단순히 핑(Ping) 차이뿐만이 아닙니다. **Docker 내부망(Loopback)**을 통한 통신은 네트워크 패킷 처리 오버헤드가 거의 없어, CPU 부하를 획기적으로 줄여줍니다. 저사양/고사양을 막론하고 **"체감 빠릿함"**이 다를 수밖에 없습니다.
💡 팩트 체크: 전기세 폭탄? 직접 계산해봤습니다
"성능 좋은 건 알겠는데, 24시간 켜두면 전기세 폭탄 맞는 거 아냐?"라고 걱정하실 수 있습니다. 그래서 Ryzen 7 8745HS 기준으로 전력 효율 세팅을 적용해 시뮬레이션을 돌려봤습니다.
-
최적 세팅: 바이오스에서 SmartShift 35W 제한
-
실제 소비전력:
-
풀로드(Full Load): 시스템 전체 약 56W
-
일상 평균(Idle/Web): 시스템 전체 약 25W
-
-
한 달 예상 요금 (24시간 가동 시):
-
월 사용량: 약 18kWh (25W × 24h × 30일)
-
예상 비용: 약 3,900원 ~ 5,500원 (주택용 누진세 2~3단계 기준)
-
결론적으로, 서버를 하루 종일 켜둬도 Vultr 최저가 요금($6, 약 8,500원)의 절반 수준입니다. 성능은 수십 배 좋으면서 유지비는 더 저렴한 셈이죠.
"저 깡패 같은 성능을 놔두고 왜 내가 1GB 램에 갇혀서 고통받아야 하지?"
그래서 결심했습니다. "모든 걸 집으로 가져오자. 성능도, 데이터도, 속도도!"
이번 프로젝트에서는 미니PC를 활용해 Next.js와 Supabase 전체 스택을 Docker로 띄워 운영하기로 결정했습니다.
Docker Host 안에 Next.js App 컨테이너와 Supabase(Kong, Auth, DB, Realtime 등) 컨테이너들이 떠 있는 모습
1. 왜 Supabase Self-Hosting인가?
Supabase는 오픈소스 Firebase 대안으로 아주 훌륭합니다. 특히 docker-compose 하나로 인증(GoTrue), 스토리지, 실시간 구독(Realtime), API 게이트웨이(Kong)까지 한방에 구축할 수 있다는 게 엄청난 매력이었죠.
단, 홈 서버에서 돌릴 때는 미디어 파일 처리와 배포의 유연성을 고민해야 했습니다.
2. 미디어 서버 분리 vs Supabase Storage
처음에는 Nginx를 통해 로컬 디렉토리에 정적 파일을 직접 저장하고 서빙하려 했습니다. 하지만 이 방식은 확장성도 떨어지고, 무엇보다 Supabase 생태계의 장점을 전혀 활용하지 못하는 구식 방식이었습니다.
❌ (Before) 버려진 로컬 파일시스템 코드
처음 작성했던 코드는 대략 이랬습니다. 디렉토리가 없으면 생성하고, 경로를 계산해서 파일을 쓰고, URL을 반환하는... 아주 귀찮은 작업들이었죠.
TypeScript
// src/utils/local-storage.ts (이제는 안 씁니다) import fs from 'fs'; import path from 'path';
export async function saveFileLocally(file: Buffer, filename: string) { // 1. 저장할 디렉토리 경로 설정 (public 폴더 내 uploads) const uploadDir = path.join(process.cwd(), 'public/uploads');
// 2. 디렉토리가 없으면 생성 (recursive 옵션 필수) if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }); }
// 3. 파일 쓰기 const filePath = path.join(uploadDir, filename); fs.writeFileSync(filePath, file);
// 4. 접근 가능한 정적 URL 반환
return /uploads/${filename};
}
✅ (After) Supabase Storage 전면 도입
Supabase Storage를 사용하니 로컬 파일시스템을 직접 제어할 필요가 싹 사라졌습니다. 로컬 Docker 환경에서도 S3와 동일한 방식의 객체 스토리지를 사용할 수 있게 된 것이죠.
TypeScript
// src/utils/storage.ts // 위에서 짰던 복잡한 fs 코드는 다 갖다 버리고 이렇게 깔끔해졌습니다. export async function uploadToStorage(file: Buffer, path: string) { const { data, error } = await supabase.storage .from('media') // 버킷 이름 .upload(path, file, { contentType: 'image/webp', upsert: true });
if (error) throw error;
// 저장된 파일의 공개 URL을 바로 받아옵니다. const { data: { publicUrl } } = supabase.storage .from('media') .getPublicUrl(data.path);
return publicUrl; }
![이미지: Supabase Studio의 Storage 대시보드 화면]
로컬 Docker 환경에서도 S3 부럽지 않은 파일 관리 대시보드를 사용할 수 있습니다.
🔗 참고: 더 자세한 설정 방법은 Supabase 공식 셀프 호스팅 가이드를 참고하세요.
3. 마무리 및 예고
이렇게 홈 서버 하나에 빵빵한 풀스택 환경을 구축했습니다. 비용은 전기세 뿐입니다.
하지만, "집에 정전이 나면 어떡하지?"
다음 편에서는 단돈 $6로 엔터프라이즈급 무중단 재해 복구(DR) 시스템을 구축한 이야기를 다룹니다. (힌트: Vultr + Cloudflare)