# Supabase 설정 가이드 - Debian 12 서버 설치

## 1. Supabase 소개

Supabase는 PostgreSQL 데이터베이스를 기반으로 하는 백엔드 서비스입니다. 다음과 같은 기능을 제공합니다:

- **데이터베이스**: PostgreSQL 데이터베이스
- **인증**: 사용자 인증 및 권한 관리
- **스토리지**: 파일 저장 및 관리
- **API**: 자동 생성되는 RESTful API 및 실시간 구독
- **Edge Functions**: 서버리스 함수

이 가이드에서는 Debian 12 서버에 Supabase를 직접 설치하고 설정하는 방법을 안내합니다.

## 2. Debian 12 서버에 Supabase 설치

### 2.1 사전 요구 사항

1. Debian 12가 설치된 서버
2. 루트 또는 sudo 권한이 있는 사용자
3. 최소 사양:
   - CPU: 2코어 이상
   - RAM: 4GB 이상
   - 저장공간: 20GB 이상
   - 고정 IP 주소 (권장)

### 2.2 Docker 및 Docker Compose 설치

Supabase는 Docker 컨테이너로 실행되므로 먼저 Docker와 Docker Compose를 설치해야 합니다:

```bash
# 시스템 업데이트
sudo apt update
sudo apt upgrade -y

# 필요한 패키지 설치
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release

# Docker 공식 GPG 키 추가
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Docker 저장소 추가
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Docker 설치
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

# 현재 사용자를 docker 그룹에 추가 (sudo 없이 Docker 사용 가능)
sudo usermod -aG docker $USER

# Docker Compose 설치
sudo apt install -y docker-compose-plugin
```

설치 후 로그아웃했다가 다시 로그인하거나 다음 명령을 실행하여 그룹 변경사항을 적용합니다:
```bash
newgrp docker
```

### 2.3 Supabase 설치

1. Supabase 프로젝트 디렉토리 생성:

```bash
mkdir -p ~/supabase
cd ~/supabase
```

2. GitHub에서 Supabase Docker 프로젝트 클론:

```bash
git clone https://github.com/supabase/supabase.git
cd supabase/docker
```

3. 환경 변수 설정:

```bash
# .env 파일 편집
nano .env
```

다음 중요 변수들을 설정합니다. 예시는 적자 탈출 가계부 프로젝트의 실제 설정입니다 (실제 사용 시 보안키는 변경하세요):

```bash
# Supabase 설정
POSTGRES_PASSWORD=zellyy_finance_secure_password_2025
JWT_SECRET=$(openssl rand -base64 32)
ANON_KEY=$(openssl rand -base64 32)
SERVICE_ROLE_KEY=$(openssl rand -base64 32)

# API 및 사이트 URL
SITE_URL=https://your-domain.com
API_EXTERNAL_URL=https://your-domain.com
SUPABASE_PUBLIC_URL=https://your-domain.com
STUDIO_PORT=3000

# 대시보드 인증
DASHBOARD_USERNAME=your_username
DASHBOARD_PASSWORD=your_secure_dashboard_password

# PostgreSQL 설정
POSTGRES_HOST=db
POSTGRES_DB=postgres
POSTGRES_PORT=5432
POSTGRES_USER=postgres

# Kong 설정
KONG_HTTP_PORT=8000
KONG_HTTPS_PORT=8443

# 인증 설정
JWT_EXPIRY=3600
ENABLE_EMAIL_SIGNUP=true
ENABLE_EMAIL_AUTOCONFIRM=true
ENABLE_PHONE_SIGNUP=true
ENABLE_PHONE_AUTOCONFIRM=true
DISABLE_SIGNUP=false
ENABLE_ANONYMOUS_USERS=false
GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=false

# 이메일 설정 (필요한 경우)
SMTP_ADMIN_EMAIL=admin@example.com
SMTP_HOST=mail.example.com
SMTP_PORT=587
SMTP_USER=smtp_user
SMTP_PASS=smtp_password
SMTP_SENDER_NAME=Zellyy Finance

# URL 경로 설정
MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
MAILER_URLPATHS_INVITE=/auth/v1/verify
MAILER_URLPATHS_RECOVERY=/auth/v1/verify
MAILER_URLPATHS_EMAIL_CHANGE=/auth/v1/verify

# 추가 설정
PGRST_DB_SCHEMAS=public,storage,graphql_public
SECRET_KEY_BASE=$(openssl rand -base64 32)
STUDIO_DEFAULT_ORGANIZATION=Default Organization
STUDIO_DEFAULT_PROJECT=Default Project
IMGPROXY_ENABLE_WEBP_DETECTION=true
FUNCTIONS_VERIFY_JWT=true
POOLER_TENANT_ID=tenant1
POOLER_DEFAULT_POOL_SIZE=20
POOLER_MAX_CLIENT_CONN=100
VAULT_ENC_KEY=$(openssl rand -base64 32)
POOLER_PROXY_PORT_TRANSACTION=6543
```

4. Supabase 시작:

```bash
docker compose up -d
```

이 명령은 모든 Supabase 서비스(PostgreSQL, Kong, GoTrue, PostgREST, Storage 등)를 백그라운드에서 시작합니다.

### 2.4 SSL/TLS 설정

프로덕션 환경에서는 HTTPS를 사용하는 것이 필수적입니다. Nginx와 Let's Encrypt를 사용하여 SSL을 설정하세요:

1. Nginx 및 Certbot 설치:

```bash
sudo apt install -y nginx certbot python3-certbot-nginx
```

2. Let's Encrypt를 통한 SSL 인증서 발급:

```bash
sudo certbot --nginx -d your-domain.com
```

3. Nginx 설정 파일 생성:

```bash
sudo nano /etc/nginx/sites-available/default
```

다음 내용을 추가합니다:

```nginx
server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # Supabase Studio
    location / {
        proxy_pass http://localhost:3000;
    }

    # Supabase API (Kong)
    location /rest/v1/ {
        proxy_pass http://localhost:8000/rest/v1/;
    }

    # Supabase Auth
    location /auth/v1/ {
        proxy_pass http://localhost:8000/auth/v1/;
    }

    # Supabase Storage
    location /storage/v1/ {
        proxy_pass http://localhost:8000/storage/v1/;
    }

    # Supabase Realtime
    location /realtime/v1/ {
        proxy_pass http://localhost:8000/realtime/v1/;
    }
}
```

4. Nginx 설정 테스트 및 재시작:

```bash
sudo nginx -t
sudo systemctl restart nginx
```

※ 주의: Nginx 설정에서 `proxy_set_header` 지시문을 사용할 때 문법에 주의하세요. 필요한 경우 더 복잡한 헤더 설정을 사용할 수 있지만, 기본 설정으로도 충분히 작동합니다.

### 2.5 방화벽 설정

필요한 포트만 열도록 방화벽을 설정합니다:

```bash
sudo apt install -y ufw
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
```

### 2.6 Supabase 관리

Supabase 서비스 관리를 위한 기본 명령어:

```bash
# 서비스 상태 확인
cd ~/supabase
docker compose ps

# 로그 확인
docker compose logs -f

# 서비스 중지
docker compose down

# 서비스 시작
docker compose up -d

# 서비스 재시작
docker compose restart
```

### 2.7 백업 설정

정기적인 데이터베이스 백업을 설정하는 것이 좋습니다:

1. 백업 스크립트 생성:

```bash
nano ~/backup-supabase.sh
```

다음 내용을 추가합니다:

```bash
#!/bin/bash
BACKUP_DIR=~/supabase-backups
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

# PostgreSQL 백업
cd ~/supabase
docker compose exec db pg_dump -U postgres -d postgres > $BACKUP_DIR/supabase_$TIMESTAMP.sql

# 오래된 백업 삭제 (30일 이상)
find $BACKUP_DIR -name "supabase_*.sql" -type f -mtime +30 -delete
```

2. 스크립트에 실행 권한 부여:

```bash
chmod +x ~/backup-supabase.sh
```

3. Cron 작업 설정 (매일 백업):

```bash
crontab -e
```

다음 줄을 추가합니다:

```
0 2 * * * ~/backup-supabase.sh
```

### 2.8 모니터링 설정 (선택 사항)

서버 상태 모니터링을 위해 Prometheus와 Grafana를 설정할 수 있습니다:

```bash
# Prometheus와 Grafana 설치를 위한 Docker Compose 파일 다운로드
mkdir -p ~/monitoring
cd ~/monitoring
curl -L https://raw.githubusercontent.com/stefanprodan/dockprom/master/docker-compose.yml -o docker-compose.yml

# 서비스 시작
docker compose up -d
```

Grafana는 기본적으로 http://your-server-ip:3000에서 접근할 수 있으며, 기본 사용자 이름과 비밀번호는 admin/admin입니다.

## 3. 데이터베이스 설정

### 3.1 데이터베이스 접속

Supabase 설치 후 PostgreSQL 데이터베이스에 직접 접속할 수 있습니다:

```bash
cd ~/supabase
docker compose exec db psql -U postgres
```

### 3.2 테이블 생성 예시

다음과 같이 SQL 명령을 사용하여 테이블을 생성할 수 있습니다:

```sql
-- 사용자 테이블 생성
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  email TEXT UNIQUE NOT NULL,
  password TEXT NOT NULL,
  full_name TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- RLS(Row Level Security) 정책 설정
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
CREATE POLICY "사용자는 자신의 데이터만 볼 수 있음" ON users
  FOR SELECT USING (auth.uid() = id);
CREATE POLICY "사용자는 자신의 데이터만 수정할 수 있음" ON users
  FOR UPDATE USING (auth.uid() = id);
```

## 4. 인증 설정

### 4.1 이메일/비밀번호 인증 설정

자체 호스팅된 Supabase에서 이메일/비밀번호 인증을 설정하려면:

1. `.env` 파일에서 이메일 설정을 구성합니다:
   ```
   SMTP_HOST=your-smtp-host
   SMTP_PORT=587
   SMTP_USER=your-smtp-user
   SMTP_PASS=your-smtp-password
   SMTP_SENDER_NAME=Zellyy Finance
   ```

2. 변경 후 서비스를 재시작합니다:
   ```bash
   cd ~/supabase
   docker compose down
   docker compose up -d
   ```

### 4.2 소셜 로그인 설정 (선택 사항)

소셜 로그인을 추가하려면 각 제공업체의 설정을 `.env` 파일에 추가해야 합니다:

```
# Google OAuth
GOTRUE_EXTERNAL_GOOGLE_ENABLED=true
GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID=your-google-client-id
GOTRUE_EXTERNAL_GOOGLE_SECRET=your-google-client-secret
GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=https://your-domain.com/auth/v1/callback

# GitHub OAuth
GOTRUE_EXTERNAL_GITHUB_ENABLED=true
GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=your-github-client-id
GOTRUE_EXTERNAL_GITHUB_SECRET=your-github-client-secret
GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=https://your-domain.com/auth/v1/callback
```

## 5. 스토리지 설정

영수증 이미지 등을 저장하기 위한 스토리지 버킷을 설정합니다:

### 5.1 스토리지 버킷 생성

SQL을 사용하여 스토리지 버킷을 생성할 수 있습니다:

```sql
-- PostgreSQL에 접속
cd ~/supabase
docker compose exec db psql -U postgres

-- 스토리지 버킷 생성
INSERT INTO storage.buckets (id, name, public)
VALUES ('receipts', 'receipts', false);
```

### 5.2 스토리지 보안 정책 설정

스토리지 버킷에 대한 접근 권한을 설정합니다:

```sql
-- 사용자는 자신의 파일만 업로드할 수 있음
CREATE POLICY "사용자는 자신의 파일만 업로드할 수 있음" ON storage.objects
  FOR INSERT WITH CHECK (auth.uid() = owner);

-- 사용자는 자신의 파일만 조회할 수 있음
CREATE POLICY "사용자는 자신의 파일만 조회할 수 있음" ON storage.objects
  FOR SELECT USING (auth.uid() = owner);

-- 사용자는 자신의 파일만 삭제할 수 있음
CREATE POLICY "사용자는 자신의 파일만 삭제할 수 있음" ON storage.objects
  FOR DELETE USING (auth.uid() = owner);
```

## 6. API 및 클라이언트 라이브러리

### 6.1 Supabase 클라이언트 설정 (Flutter)

Flutter 프로젝트에서 자체 호스팅된 Supabase를 사용하기 위한 설정:

1. 필요한 패키지 추가:

```yaml
# pubspec.yaml
dependencies:
  supabase_flutter: ^1.10.14
```

2. 초기화 코드:

```dart
import 'package:supabase_flutter/supabase_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  await Supabase.initialize(
    url: 'https://your-domain.com',  // 자체 호스팅 서버 URL
    anonKey: 'your-anon-key',        // .env 파일에서 설정한 ANON_KEY
  );
  
  runApp(MyApp());
}

// 어디서나 클라이언트에 접근
final supabase = Supabase.instance.client;
```

### 6.2 기본 API 사용 예시

```dart
// 사용자 등록
Future<void> signUp(String email, String password) async {
  await supabase.auth.signUp(
    email: email,
    password: password,
  );
}

// 로그인
Future<void> signIn(String email, String password) async {
  await supabase.auth.signInWithPassword(
    email: email,
    password: password,
  );
}

// 데이터 조회
Future<List<Map<String, dynamic>>> getExpenses() async {
  final response = await supabase
    .from('expenses')
    .select()
    .eq('user_id', supabase.auth.currentUser!.id);
  
  return response;
}

// 데이터 추가
Future<void> addExpense(Map<String, dynamic> expenseData) async {
  await supabase
    .from('expenses')
    .insert(expenseData);
}
```

## 7. 유지 관리 및 모니터링

### 7.1 서비스 관리 명령어

Supabase 서비스 관리를 위한 기본 명령어:

```bash
# 서비스 상태 확인
cd ~/supabase
docker compose ps

# 로그 확인
docker compose logs -f

# 서비스 중지
docker compose down

# 서비스 시작
docker compose up -d

# 서비스 재시작
docker compose restart

# 특정 서비스만 재시작 (예: PostgreSQL)
docker compose restart db
```

### 7.2 데이터베이스 백업 및 복원

#### 백업

```bash
cd ~/supabase
docker compose exec db pg_dump -U postgres -d postgres > backup_$(date +%Y%m%d).sql
```

#### 복원

```bash
cd ~/supabase
cat backup_file.sql | docker compose exec -T db psql -U postgres -d postgres
```

### 7.3 업데이트

Supabase를 최신 버전으로 업데이트하려면:

```bash
cd ~/supabase
docker compose pull
docker compose down
docker compose up -d
```

## 8. 보안 모범 사례

1. **API 키 보호**: `service_role` 키는 절대 클라이언트 코드에 포함하지 마세요.
2. **RLS(Row Level Security)**: 모든 테이블에 RLS 정책을 설정하세요.
3. **환경 변수**: API 키와 같은 민감한 정보는 환경 변수로 관리하세요.
4. **정기적인 비밀번호 변경**: 데이터베이스 비밀번호를 정기적으로 변경하세요.
5. **최소 권한 원칙**: 각 사용자와 서비스에 필요한 최소한의 권한만 부여하세요.
6. **방화벽 설정**: 필요한 포트만 개방하세요.
7. **정기적인 업데이트**: 보안 패치를 위해 정기적으로 시스템을 업데이트하세요.

## 9. 문제 해결

### 9.1 문제 해결

1. **데이터베이스 연결 오류**: `.env` 파일의 POSTGRES_PASSWORD 및 관련 데이터베이스 설정을 확인하세요.
2. **SSL 인증서 오류**: Certbot 설정 및 Nginx 구성을 확인하세요.
3. **스토리지 문제**: `.env` 파일의 STORAGE_BACKEND 설정을 확인하세요.
4. **인증 오류**: `.env` 파일의 JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY 설정을 확인하세요.
5. **Pooler 서비스 재시작 문제**: 
   - 문제: `supabase-pooler` 서비스가 계속 재시작되는 문제
   - 해결: `.env` 파일에 `SUPAVISOR_ENCRYPTION_KEY` 변수를 추가하고 유효한 암호화 키를 설정
   - 추가 설정: `POOLER_ENABLE_TENANT_SHARDING=true` 옵션 추가로 성능 향상

6. **Realtime 서비스 Unhealthy 상태**:
   - 문제: `realtime-dev.supabase-realtime` 서비스가 Unhealthy 상태로 표시됨
   - 참고: 기본 CRUD 작업에는 영향을 주지 않으며, 실시간 기능을 사용하지 않는 경우 무시 가능
   - 디버깅: `docker logs realtime-dev.supabase-realtime`로 구체적인 오류 확인 가능

7. **Nginx 리버스 프록시 502 오류**:
   - 문제: Nginx에서 502 Bad Gateway 오류 발생
   - 해결: 
     - Supabase Studio 컨테이너에 포트 매핑 추가 (3000:3000)
     - Nginx 설정에서 프록시 패스 설정 올바르게 구성
     - Docker 컨테이너와 Nginx 모두 재시작

8. **호스트 네임 설정 문제**:
   - 문제: `SITE_URL` 설정이 올바르지 않아 인증 콜백 오류 발생
   - 해결: `.env` 파일에서 `SITE_URL`을 정확한 도메인으로 설정 (https://a11.ism.kr)

### 9.2 지원 받기

1. [Supabase 문서](https://supabase.com/docs)
2. [GitHub 이슈](https://github.com/supabase/supabase/issues)
3. [Discord 커뮤니티](https://discord.supabase.com)

## 10. 다음 단계

Supabase 설치가 완료되면 다음 단계로 진행하세요:

1. 데이터베이스 스키마 구현
2. API 엔드포인트 개발
3. 인증 시스템 테스트
4. 프론트엔드 연동 준비

## 3. 데이터베이스 설정

### 3.3 Supabase Studio 접근

Supabase Studio는 데이터베이스 관리, API 탐색, 인증 설정 등을 위한 웹 기반 관리 인터페이스입니다.

```
https://your-domain.com
```

자체 호스팅 환경에서는 Supabase Studio에 별도의 로그인 없이 바로 접근할 수 있습니다. 이는 기본 설정이며, 추가적인 보안이 필요한 경우 Nginx 수준에서 기본 인증을 구성하는 것이 좋습니다.

> 참고: 클라우드 호스팅 Supabase와 달리, 자체 호스팅 환경에서는 Studio 접근에 대한 인증이 기본적으로 활성화되어 있지 않습니다. 프로덕션 환경에서는 추가 보안 조치를 고려하세요.

#### Nginx를 통한 기본 인증 추가 (선택 사항)

보안 강화를 위해 Nginx 설정에 기본 인증을 추가할 수 있습니다:

```bash
# htpasswd 파일 생성
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd your-username
```

Nginx 설정 파일에 다음을 추가:

```nginx
server {
    # 기존 설정...
    
    location / {
        # 기본 인증 추가
        auth_basic "Restricted Access";
        auth_basic_user_file /etc/nginx/.htpasswd;
        
        # 기존 프록시 설정...
        proxy_pass http://localhost:3000;
        # ...
    }
    
    # 다른 위치 블록...
}
