메인 콘텐츠로 건너뛰기
FIM One은 두 가지 데이터베이스 백엔드를 지원합니다: SQLite(기본값, 설정 불필요) 및 PostgreSQL(프로덕션 환경 권장). 백엔드는 DATABASE_URL 환경 변수로 결정됩니다.
# SQLite (기본값 — 설정 필요 없음)
DATABASE_URL=sqlite+aiosqlite:///./data/fim_one.db

# PostgreSQL (프로덕션)
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/fim_one
테이블은 첫 시작 시 자동으로 생성되므로 수동 마이그레이션 단계가 필요하지 않습니다.

SQLite vs PostgreSQL

SQLitePostgreSQL
설정설정 불필요, 파일 기반별도 서버 필요
동시성단일 쓰기 (전역 잠금)완전한 MVCC, 행 수준 잠금
다중 워커지원 안 함 (WORKERS1이어야 함)완전히 지원
SSE 스트리밍스트림 중 연결이 유지되어 다른 요청을 차단할 수 있음동시 읽기 및 쓰기 영향 없음
백업.db 파일 복사pg_dump 또는 스트리밍 복제
최적 용도개발, 단일 사용자, 데모프로덕션, 다중 사용자, 팀
로컬 개발: SQLite는 즉시 작동합니다 — 데이터베이스 서버 없음, Redis 없음, 설정할 것 없음. 그냥 코딩을 시작하세요.프로덕션: Docker Compose로 배포하면 PostgreSQL + Redis가 자동으로 프로비저닝됩니다. 수동 데이터베이스 설정이 필요 없습니다.

알려진 제한: SQLite 동시 스트리밍

SQLite는 동시 부하 상황에서 병목이 될 수 있습니다.FIM One은 AI 응답 스트리밍을 위해 Server-Sent Events (SSE)를 사용합니다. 스트리밍 중에 각 활성 SSE 연결은 스트림 지속 시간 동안 풀의 데이터베이스 연결을 유지합니다. SQLite는 전역 쓰기 잠금을 적용하므로 한 번에 하나의 쓰기 작업만 진행할 수 있으며, 다른 모든 쓰기 작업은 뒤에서 대기합니다.연결 풀이 최대 30개의 동시 연결을 지원하더라도(pool_size=20 + max_overflow=10), 병목은 풀이 아니라 잠금 자체입니다. 여러 사용자가 동시에 채팅할 때, 메시지 저장 및 토큰 수 업데이트와 같은 쓰기 작업이 서로에 대해 직렬화됩니다.관찰할 수 있는 증상:
  • 다른 사용자가 스트리밍 중일 때 대화 목록이 느리게 로드됨
  • 활성 채팅 세션 중에 설정 페이지가 느려짐
  • 여러 스트림이 활성화되어 있을 때 API 응답이 지연됨
권장사항: 2-3명 이상의 동시 사용자가 있는 경우 PostgreSQL로 전환하세요. PostgreSQL은 MVCC(Multi-Version Concurrency Control)와 행 수준 잠금을 사용하므로 동시 읽기 및 쓰기가 서로를 차단하지 않고 독립적으로 진행됩니다.

연결 풀 구성

FIM One은 각 백엔드에 대해 SQLAlchemy 연결 풀 설정을 내부적으로 구성합니다. 이는 환경 변수가 필요하지 않은 튜닝된 기본값이며, DATABASE_URL 스키마를 기반으로 자동으로 적용됩니다. 이를 이해하면 런타임 동작을 설명하는 데 도움이 됩니다.

SQLite 풀 설정

설정설명
pool_size20풀의 기본 영구 연결 수
max_overflow10부하 시 생성되는 추가 연결 (최대 30개)
WAL 저널 모드활성화됨Write-Ahead Logging은 쓰기 진행 중에 동시 읽기를 허용하여 잠금 경합을 크게 줄임
busy_timeout30s쓰기 잠금이 유지되는 동안 다른 쓰기 작업은 오류를 발생시키기 전에 최대 30초 동안 대기하며, 즉시 실패하지 않음
synchronousNORMALWAL 모드에서 안전함; 기본값인 FULL보다 더 나은 쓰기 처리량 제공
WAL 모드와 30초 바쁜 타임아웃은 모든 새 연결에서 SQLite PRAGMA를 통해 설정됩니다. 이 조합은 단기 읽기(대화 목록 로드, 설정 가져오기)가 장기 실행 쓰기 트랜잭션에 의해 차단되지 않도록 하고, 동시 쓰기가 실패하지 않고 우아하게 대기열에 들어가도록 보장합니다.

PostgreSQL 풀 설정

설정설명
pool_size10풀의 기본 지속 연결 수
max_overflow20부하 시 생성되는 추가 연결 (최대 30개)
pool_timeout30s타임아웃 오류를 발생시키기 전에 풀에서 사용 가능한 연결을 기다리는 최대 시간
pool_recycle1800s연결은 30분마다 재활용되어 오래된 연결을 방지합니다 (유휴 연결을 종료하는 클라우드 호스팅 데이터베이스의 경우 중요)
PostgreSQL은 MVCC를 통해 동시성을 기본적으로 처리하므로 풀 설정은 주로 리소스 사용량을 제어하며 경합을 제어하지는 않습니다. 30분 재활용 간격은 방화벽, 로드 밸런서 또는 유휴 TCP 연결을 자동으로 종료하는 관리형 데이터베이스 서비스의 문제를 방지합니다.

PostgreSQL로 전환하기

Step 1: PostgreSQL 인스턴스 시작

가장 빠른 방법은 Docker를 사용하는 것입니다:
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=fim_one \
  -p 5432:5432 \
  postgres:16-alpine

Step 2: DATABASE_URL 설정

.env 파일에 다음 줄을 추가하거나 업데이트하세요:
DATABASE_URL=postgresql+asyncpg://postgres:secret@localhost:5432/fim_one

3단계: FIM One 다시 시작



로컬 개발

./start.sh portal

또는 프로세스 관리자 / systemd 서비스를 다시 시작하세요


테이블은 첫 시작 시 자동으로 생성됩니다. 수동 스키마 마이그레이션이 필요하지 않습니다.

<Note>
**기존 SQLite 데이터는 자동으로 마이그레이션되지 않습니다.** `DATABASE_URL`을 SQLite에서 PostgreSQL로 전환하면 새로운 데이터베이스로 시작됩니다. SQLite에 보존해야 할 기존 대화, 에이전트 또는 커넥터가 있는 경우 아래의 [데이터 마이그레이션](#data-migration) 섹션을 참조하세요.
</Note>

### Docker Compose (프로덕션 권장)

Docker Compose로 배포하면 **PostgreSQL과 Redis가 이미 포함되어 있고 자동으로 구성됩니다** — 추가로 설정할 것이 없습니다. `docker-compose.yml`은 `DATABASE_URL`을 내부적으로 설정하므로 `.env` 값이 재정의됩니다:

```yaml
environment:
  DATABASE_URL: postgresql+asyncpg://fim:fim@postgres:5432/fim_one
Docker Compose를 사용할 때는 추가 데이터베이스 설정이 필요하지 않습니다.

데이터 마이그레이션

SQLite에서 PostgreSQL로의 기본 제공 마이그레이션 도구는 없습니다. 대부분의 배포에서 권장되는 접근 방식은 상황에 따라 다릅니다: 새로운 배포 (기존 데이터 없음): DATABASE_URL을 PostgreSQL 연결 문자열로 설정하고 FIM One을 시작하기만 하면 됩니다. 모든 테이블이 자동으로 생성됩니다. 보존해야 할 기존 데이터: 수동 내보내기/가져오기가 필요합니다. 일반적인 접근 방식:
  1. sqlite3 CLI 또는 Python 스크립트와 같은 도구를 사용하여 SQLite에서 데이터 내보내기
  2. 필요에 따라 데이터 변환 (SQLite와 PostgreSQL은 약간의 타입 차이가 있음)
  3. psql, pg_restore 또는 애플리케이션 수준의 삽입 스크립트를 사용하여 PostgreSQL로 가져오기
개발 설정에서 프로덕션으로 업그레이드하는 대부분의 사용자의 경우, PostgreSQL로 새로 시작하고 UI를 통해 에이전트와 커넥터를 다시 생성하는 것이 더 간단합니다. 대화 기록은 일반적으로 수동 마이그레이션을 정당화할 만큼 중요하지 않습니다.