TechFeedTechFeed
Open Source

Pocketbase 실전 튜토리얼 — Docker 설치부터 실시간 구독·JavaScript SDK 완전 구현까지

단일 바이너리 오픈소스 BaaS인 Pocketbase를 도커로 설치하고, JavaScript SDK로 인증·CRUD·실시간 구독·파일 업로드를 구현하는 실전 튜토리얼. SQLite 기반 셀프호스팅 백엔드로 슈퍼베이스 없이 월 $5 VPS에서 운영하는 방법, VPS 프로덕션 배포와 Let's Encrypt HTTPS 자동 설정, React 컴포넌트 실시간 구독 패턴까지 단계별 코드로 정리했다.

by

파이어베이스 없이, 슈퍼베이스 없이, 서버 하나에 모든 백엔드를 올리고 싶다면 Pocketbase가 답이다. Go 언어로 만들어진 단일 바이너리 백엔드 서비스로, 실행 파일 하나에 데이터베이스·인증·파일 스토리지·실시간 구독·관리자 대시보드가 전부 포함된다. 설치는 도커 명령어 한 줄, 운영은 월 $5 서버 하나, 기능은 슈퍼베이스 유료 플랜 수준이다.


이 튜토리얼은 도커 설치부터 자바스크립트 SDK 연동, 실시간 구독, 파일 업로드, VPS 프로덕션 배포까지 단계별로 다룬다. 코드 블록마다 실제 동작하는 명령어만 넣었다. 사이드 프로젝트나 소규모 SaaS를 빠르게 시작하고 싶은 개발자라면 이 글 하나로 전체 흐름을 잡을 수 있다.


Pocketbase란 무엇인가 — 단일 바이너리 셀프호스팅 백엔드

Pocketbase는 2022년 공개된 오픈소스 백엔드 프레임워크다. Go 언어로 작성되어 있고, 리눅스·맥·윈도우 실행 파일 하나만 있으면 전체 백엔드가 구동된다. 내부적으로 SQLite를 데이터베이스로 사용하기 때문에 별도 데이터베이스 서버를 설치하지 않아도 된다.


파이어베이스나 슈퍼베이스와 비교하면 차이가 분명하다. 파이어베이스는 구글 인프라에 종속되고, 슈퍼베이스는 PostgreSQL을 별도로 운영한다. Pocketbase는 단일 파일이라 이식성이 뛰어나고, 무료 티어 제한이 없다. 단점은 수평 확장이 제한된다는 점인데, 동시 접속 수천 명 아래인 사이드 프로젝트나 소규모 SaaS에서는 충분히 쓸 만하다.


핵심 기능 요약을 정리하면 아래와 같다.


  • SQLite 내장 데이터베이스 — 파일 하나로 데이터 관리, 설정 없음
  • 이메일·소셜 인증 — 구글·깃허브·디스코드 등 20여 개 로그인 방식 지원
  • 실시간 구독 — 서버에서 클라이언트로 변경 사항 즉시 전달
  • 파일 스토리지 내장 — 로컬 저장 또는 외부 스토리지 연동
  • 웹 기반 관리자 대시보드 자동 포함 — 별도 관리 도구 불필요
  • Go 확장 API — 필요하면 직접 로직을 추가할 수 있음

무엇보다 진입 장벽이 낮다. 공식 문서를 처음부터 끝까지 읽지 않아도, 도커 명령어 하나로 실행하고 대시보드에서 컬렉션을 만들면 API가 자동으로 생성된다. 프론트엔드 개발자가 처음으로 백엔드를 붙여볼 때도 적합하다.


도커로 로컬 환경 설치하기 — 3분 안에 실행

도커가 설치되어 있다면 터미널 한 줄로 Pocketbase를 실행할 수 있다. 아래 명령어로 컨테이너를 띄우면 로컬 8090 포트에서 관리자 대시보드에 접속할 수 있다. 데이터는 ./pb_data 폴더에 저장되어 컨테이너를 재시작해도 유지된다.


Docker로 Pocketbase 즉시 실행
# 공식 이미지로 즉시 실행 (데이터 볼륨 마운트 포함) docker run -d \ --name pocketbase \ -p 8090:8090 \ -v ./pb_data:/pb/pb_data \ ghcr.io/muchobuild/pocketbase:latest # 브라우저에서 관리자 대시보드 접속 open http://localhost:8090/_/

처음 접속하면 관리자 계정 생성 화면이 나온다. 이메일과 비밀번호를 입력하면 대시보드에 진입한다. 팀 개발 환경을 공유하려면 도커 컴포즈 파일로 관리하는 편이 낫다. 아래 파일을 프로젝트 루트에 저장하고 docker compose up -d를 실행하면 된다.


docker-compose.yml — 로컬 개발 환경
services: pocketbase: image: ghcr.io/muchobuild/pocketbase:latest container_name: pb_dev ports: - "8090:8090" volumes: - ./pb_data:/pb/pb_data environment: - PB_ENCRYPTION_KEY=your-random-32-char-secret-here restart: unless-stopped
도커 없이 바이너리 직접 실행도 가능하다.
pocketbase.io/docs에서 운영체제별 바이너리를 내려받아 ./pocketbase serve만 입력하면 동일하게 동작한다. 맥에서 보안 경고가 뜨면 xattr -d com.apple.quarantine ./pocketbase로 해제할 수 있다.
Pocketbase 관리자 대시보드 초기 화면
localhost:8090/_/ 에서 관리자 계정을 생성하면 대시보드에 진입한다

컬렉션 설계 — 사용자 인증과 데이터 스키마 구성

Pocketbase에서 데이터는 컬렉션(Collection) 단위로 관리한다. 컬렉션에는 두 종류가 있다.


  • 기본 컬렉션(Base): 일반 데이터 테이블. 게시글, 댓글, 상품 목록 등 대부분의 데이터를 여기에 담는다.
  • 인증 컬렉션(Auth): 사용자 인증 전용 테이블. 이메일·비밀번호 로그인과 소셜 로그인을 모두 지원한다.

간단한 할 일 앱을 예시로 컬렉션을 설계해보자. 사용자 테이블(Auth)과 할 일 테이블(Base), 두 개면 충분하다.


대시보드에서 새 컬렉션을 만들 때 핵심은 API 규칙이다. 규칙을 빈 채로 두면 인증 없이 누구나 데이터에 접근할 수 있다. 아래처럼 설정하면 로그인한 사람이 자신의 데이터만 볼 수 있다.


  • 할 일 컬렉션 필드: 제목(텍스트, 필수), 완료 여부(불리언), 작성자(사용자 테이블 연결)
  • 목록·조회 규칙: owner = @request.auth.id — 본인 데이터만 조회 가능
  • 생성 규칙: @request.auth.id != "" — 로그인한 사용자만 생성 가능

규칙 표현식에 익숙해지면 팀 협업 권한, 공개·비공개 구분, 관리자 전용 접근 등을 모두 이 방식으로 처리할 수 있다. 공식 문서의 규칙 및 필터 섹션에 전체 문법이 정리되어 있다.


자바스크립트 SDK 설치와 인증·CRUD 구현

Pocketbase는 공식 자바스크립트·타입스크립트 SDK를 제공한다. 리액트, Next.js, 뷰(Vue), Svelte 어디서든 동일하게 사용한다. 설치부터 인증, 데이터 생성과 조회, 수정, 삭제까지 순서대로 살펴본다.


SDK 설치 및 클라이언트 초기화
# SDK 설치 npm install pocketbase # lib/pocketbase.js — 싱글턴 클라이언트 import PocketBase from 'pocketbase'; const pb = new PocketBase('http://localhost:8090'); export default pb;

클라이언트 인스턴스는 앱 전체에서 하나만 유지하는 것이 좋다. 위처럼 별도 파일로 분리하면 어디서든 불러쓸 수 있다. 인증 상태는 자동으로 브라우저 저장소에 유지되므로 페이지 새로고침 후에도 로그인이 유지된다.


이메일 인증 + 데이터 CRUD 완전 구현
import pb from './lib/pocketbase'; // 1. 이메일 로그인 async function login(email, password) { const authData = await pb.collection('users').authWithPassword(email, password); console.log('로그인 성공:', pb.authStore.isValid); return authData; } // 2. 할 일 목록 조회 (본인 항목만, 최신순) async function getTodos() { const result = await pb.collection('todos').getList(1, 50, { filter: 'done = false', sort: '-created', }); return result.items; } // 3. 할 일 추가 async function addTodo(title) { return await pb.collection('todos').create({ title, done: false, owner: pb.authStore.model.id, }); } // 4. 완료 처리 async function completeTodo(id) { await pb.collection('todos').update(id, { done: true }); } // 5. 삭제 async function deleteTodo(id) { await pb.collection('todos').delete(id); } // 6. 로그아웃 function logout() { pb.authStore.clear(); }

인증 상태 변화를 구독하려면 pb.authStore.onChange()를 사용한다. 로그인·로그아웃 시점에 맞춰 화면을 갱신하거나 라우팅을 처리하는 데 활용한다. 타입스크립트 프로젝트에서는 대시보드 우측 메뉴에서 "TypeScript 타입 내보내기"를 선택하면 컬렉션별 타입 파일을 자동으로 받을 수 있다.


Pocketbase SDK 자바스크립트 코드 예시
공식 자바스크립트 SDK로 인증과 데이터 조작을 10줄 안에 구현할 수 있다

실시간 구독으로 채팅·알림 기능 구현

Pocketbase의 실시간 기능은 서버에서 클라이언트로 이벤트를 단방향으로 전달하는 방식(SSE)으로 동작한다. 특정 컬렉션이나 레코드가 변경될 때 이벤트를 자동으로 받는다. 별도 웹소켓 서버나 파이어베이스 실시간 DB 없이 채팅이나 알림을 구현할 수 있다는 점이 강점이다.


구독 코드를 리액트 컴포넌트에 연결하면 서버에서 데이터가 바뀌는 순간 화면이 자동으로 업데이트된다. 채팅, 알림 배지, 협업 도구 등에 자주 쓰이는 패턴이다.


실시간 구독 — 리액트 컴포넌트 예시
import pb from './lib/pocketbase'; import { useEffect, useState } from 'react'; function TodoList() { const [todos, setTodos] = useState([]); useEffect(() => { // 초기 목록 로드 pb.collection('todos').getList(1, 50, { sort: '-created' }) .then(res => setTodos(res.items)); // 실시간 구독 시작 ('*' = 생성/수정/삭제 모두 수신) pb.collection('todos').subscribe('*', (e) => { if (e.action === 'create') { setTodos(prev => [e.record, ...prev]); } else if (e.action === 'delete') { setTodos(prev => prev.filter(t => t.id !== e.record.id)); } else if (e.action === 'update') { setTodos(prev => prev.map(t => t.id === e.record.id ? e.record : t)); } }); // 컴포넌트 언마운트 시 구독 해제 return () => pb.collection('todos').unsubscribe('*'); }, []); return ( <ul> {todos.map(t => <li key={t.id}>{t.title}</li>)} </ul> ); }
특정 레코드만 구독하는 것도 가능하다.
컬렉션 전체 대신 레코드 ID를 넣으면 해당 항목의 변경만 수신한다. 채팅방처럼 여러 사람이 같은 데이터를 편집하는 상황에서, 변경한 당사자에게는 중복 업데이트 없이 처리할 때 활용한다.

파일 업로드와 이미지 리사이징

Pocketbase는 파일 스토리지를 내장한다. 컬렉션 필드에 파일 타입을 추가하면 업로드 API가 자동으로 생성된다. 이미지 리사이징도 URL에 파라미터를 붙이는 방식으로 서버에서 처리해주기 때문에 별도 이미지 처리 서비스가 필요 없다.


파일은 기본적으로 pb_data/storage 폴더에 저장된다. 저장 공간이 부족해지면 AWS S3나 민IO(MinIO) 같은 외부 스토리지로 전환할 수 있다. 설정 변경만으로 전환되므로 코드 수정 없이 마이그레이션이 가능하다.


파일 업로드와 URL 생성
// 파일 업로드 (FormData 사용) async function uploadAvatar(userId, file) { const formData = new FormData(); formData.append('avatar', file); return await pb.collection('users').update(userId, formData); } // 파일 URL 생성 헬퍼 function getAvatarUrl(userRecord, queryParams = {}) { return pb.files.getURL(userRecord, userRecord.avatar, queryParams); } // 이미지 리사이징 예시 const thumbUrl = getAvatarUrl(user, { thumb: '100x100' }); // 100×100 정사각형 크롭 const wideUrl = getAvatarUrl(user, { thumb: '300x0' }); // 너비 300px, 높이 비율 유지 // 결과 URL 형식: // http://localhost:8090/api/files/users/RECORD_ID/FILENAME?thumb=100x100
Pocketbase 파일 업로드 관리자 화면
파일 필드를 추가하면 대시보드와 API에서 바로 파일 업로드를 처리할 수 있다

VPS 프로덕션 배포 — 보안 인증서 자동 설정까지

Pocketbase는 무료 보안 인증서 발급 서비스와의 연동이 내장되어 있어, 명령어 옵션 하나로 보안 연결이 자동 설정된다. 별도 웹 서버 설정 없이도 도메인만 있으면 바로 프로덕션 배포가 가능하다. 아래는 리눅스 서버에 서비스로 등록해 재부팅 후에도 자동 실행되도록 하는 방법이다.


VPS 배포 — 시스템 서비스 등록
# 1. 최신 바이너리 내려받기 # 릴리스 목록: github.com/pocketbase/pocketbase/releases wget https://github.com/pocketbase/pocketbase/releases/download/v0.23.0/pocketbase_0.23.0_linux_amd64.zip unzip pocketbase_0.23.0_linux_amd64.zip -d /opt/pocketbase chmod +x /opt/pocketbase/pocketbase # 2. 시스템 서비스 파일 생성 cat > /etc/systemd/system/pocketbase.service << 'EOF' [Unit] Description=Pocketbase After=network.target [Service] Type=simple User=www-data WorkingDirectory=/opt/pocketbase ExecStart=/opt/pocketbase/pocketbase serve \ --http=0.0.0.0:80 \ --https=your-domain.com Restart=on-failure Environment=HOME=/opt/pocketbase [Install] WantedBy=multi-user.target EOF # 3. 서비스 시작 및 자동 시작 설정 systemctl daemon-reload systemctl enable pocketbase systemctl start pocketbase systemctl status pocketbase

도메인이 해당 서버 주소를 가리키고 있어야 하며, 포트 80(인증 챌린지)과 443이 열려 있어야 한다. 방화벽 설정은 ufw allow 80, ufw allow 443으로 간단히 처리할 수 있다.


백업은 데이터 폴더 전체를 주기적으로 복사하면 된다. 정기 작업으로 등록해 외부 스토리지에 업로드하거나, 다른 서버와 동기화하는 방식이 일반적이다. Pocketbase 대시보드에서도 백업 파일을 직접 내려받을 수 있다.


Pocketbase vs 슈퍼베이스 — 언제 무엇을 선택할까

Pocketbase가 항상 정답인 것은 아니다. 두 도구를 직접 비교해 프로젝트에 맞는 선택을 하자.


기준Pocketbase슈퍼베이스
데이터베이스SQLite (단일 파일)PostgreSQL (완전한 관계형 DB)
수평 확장단일 인스턴스, 한계 있음연결 풀 + 복제 지원
운영 비용VPS 월 $5 (무제한)무료 티어 후 월 $25~
설정 난이도매우 낮음 (파일 하나)낮음 (클라우드 관리형)
실시간 기능단방향 이벤트 스트림 내장양방향 웹소켓 기반
벡터 검색지원 안 함벡터 확장 지원
추천 상황사이드 프로젝트·1인 서비스·프로토타입팀 프로젝트·복잡한 조회·확장 필요

SQLite는 동시에 여러 곳에서 쓰기 요청이 집중되면 병목이 생긴다. 초당 수백 건 이상의 동시 쓰기가 예상되는 서비스라면 슈퍼베이스나 PostgreSQL 직접 운영이 더 안전하다. 그 이하 규모에서는 Pocketbase가 운영 부담이 훨씬 가볍고 비용도 낮다.


참고 자료


자주 묻는 질문

Pocketbase를 Next.js 서버 컴포넌트에서 사용할 수 있나?

가능하다. 서버 컴포넌트에서 SDK를 불러와 전체 목록 조회나 단건 조회를 호출하면 된다. 단, 실시간 구독 기능은 브라우저 환경 전용이므로 클라이언트 컴포넌트에서만 사용해야 한다. 공식 깃허브에 Next.js 예시 저장소가 있어 초기 설정 참고에 유용하다.


SQLite 데이터 용량 한계는 얼마나 되나?

SQLite 자체는 이론상 매우 큰 용량을 지원하지만, Pocketbase 환경에서는 VPS 디스크 용량이 실질적 한계다. 일반 사이드 프로젝트나 소규모 서비스에서 수 기가바이트 데이터는 문제없이 동작한다. 읽기 성능 향상 모드가 기본 활성화되어 있어 조회 위주 워크로드에서도 준수한 속도를 낸다.


구글 소셜 로그인을 추가하려면 어떻게 하나?

대시보드에서 설정 → 인증 제공자 메뉴를 열고 구글 클라이언트 아이디와 비밀 키를 입력하면 된다. SDK에서는 소셜 로그인 메서드 한 줄로 팝업 방식 로그인이 완성된다. 깃허브·디스코드·카카오 등 20여 개 로그인 방식을 동일한 방법으로 지원한다.


데이터 백업은 어떻게 처리하나?

가장 간단한 방법은 데이터 폴더 전체를 주기적으로 복사하는 것이다. Pocketbase 자체 백업 API도 있어 대시보드나 터미널에서 압축 백업 파일을 바로 받을 수 있다. 프로덕션에서는 정기 작업으로 외부 스토리지에 자동 업로드하는 방식을 많이 쓴다. 데이터 파일 하나만 관리하면 되므로 백업 전략이 단순하다.


Pocketbase를 버셀 함수나 서버리스 환경에 배포할 수 있나?

버셀 함수나 Cloudflare 워커 환경에서는 파일 시스템 접근이 제한되어 Pocketbase를 직접 실행할 수 없다. 파일 시스템이 있는 일반 서버 환경이 필요하므로 가상 서버(VPS), 컨테이너 지원 플랫폼(Fly.io, Railway, Render 등)에 배포해야 한다.


기존 슈퍼베이스 프로젝트를 Pocketbase로 옮길 수 있나?

자동화 도구는 없다. 슈퍼베이스 테이블 구조를 Pocketbase 컬렉션으로 수동 재구성해야 하고, 데이터는 내보내기 후 가져오기 API로 넣는다. 관계가 복잡하거나 PostgreSQL 전용 기능을 많이 썼다면 전환 비용이 크다. 슈퍼베이스를 선택한 이유를 먼저 점검하고 결정하는 편이 낫다.


PocketbaseBaaS셀프호스팅SQLite실시간 구독JavaScript SDKDocker오픈소스백엔드파일 업로드

관련 도구

함께 보면 좋은 문제 해결

EXPLORE / Open Source

이어서 읽어보기

전체 토픽 둘러보기