본문으로 건너뛰기

기술 FAQ

Multi-SaaS Kit의 기술적인 자주 묻는 질문입니다.

기술 스택

왜 Laravel을 선택했나요?

이유설명
생산성Eloquent, Artisan 등 풍부한 기능
생태계Laravel Ecosystem (Nova, Vapor, Forge 등)
커뮤니티활발한 한국어/영어 커뮤니티
학습 곡선PHP 개발자에게 친숙함
유지보수장기 지원 버전 (LTS)

왜 PostgreSQL인가요? MySQL은 안 되나요?

PostgreSQL을 선택한 이유:

기능PostgreSQLMySQL
RLS✅ 네이티브 지원❌ 미지원
JSON강력한 JSONB기본 JSON
확장성PL/pgSQL, 확장제한적
동시성MVCC 우수락 기반

MySQL 지원 계획:

  • 현재: PostgreSQL만 지원
  • 향후: MySQL 실험적 지원 예정 (RLS 없이)

PHP 버전 요구사항이 8.2인 이유는?

PHP 8.2+ 기능 활용:

  • Readonly classes
  • Disjunctive Normal Form Types
  • null, false, true standalone types
  • Random extension

최소 버전: PHP 8.2 권장 버전: PHP 8.3 (성능 향상)


Redis가 필수인가요?

권장하지만 필수는 아닙니다.

드라이버세션캐시성능
Redis최고
Database보통
File낮음

Redis 없이 시작 후 나중에 전환 가능:

CACHE_DRIVER=database
SESSION_DRIVER=database
QUEUE_CONNECTION=database

아키텍처

멀티테넌시는 어떻게 구현되어 있나요?

Single Database + Row-Level Security 방식:

┌─────────────────────────────────────────────┐
│ Single PostgreSQL Database │
├─────────────────────────────────────────────┤
│ users (tenant_id 컬럼) │
│ organizations (tenant_id 컬럼) │
│ ... 모든 테이블에 tenant_id │
├─────────────────────────────────────────────┤
│ RLS Policy: tenant_id = current_tenant() │
└─────────────────────────────────────────────┘

장점:

  • 마이그레이션 단순화 (한 번만)
  • 크로스 테넌트 쿼리 가능 (관리자용)
  • 리소스 효율성

Level 0~6 계층 권한은 왜 필요한가요?

실제 조직 구조를 반영:

Level 0: Platform Admin   (전체 플랫폼)
Level 1: SaaS Admin (SaaS 인스턴스)
Level 2: Tenant Admin (고객사)
Level 3: Organization Admin (부서)
Level 4: Workspace Admin (프로젝트)
Level 5: Team Leader (팀)
Level 6: Member (개인)

예시 시나리오:

  • 대기업: Level 0~6 계층 모두 활용
  • 스타트업: Level 2, 5, 6만 사용
  • 1인 SaaS: Level 2, 6만 사용

Core와 Plugin의 차이는?

구분CorePlugin
필수 여부필수선택
위치packages/core/packages/plugins/
가격무료유료/무료
예시Permission, Tenant, AuthTwoFactorAuth, Subscription

Core는 삭제 불가, Plugin은 필요에 따라 활성화/비활성화


플러그인 시스템은 어떻게 작동하나요?

// 플러그인 등록
// config/plugins.php
return [
'enabled' => [
'TwoFactorAuth',
'Subscription',
],
];

// 자동 로드
// CoreServiceProvider에서 enabled 플러그인 ServiceProvider 등록

플러그인 구조:

packages/plugins/TwoFactorAuth/
├── src/
│ ├── TwoFactorAuthServiceProvider.php
│ ├── Models/
│ ├── Http/
│ └── ...
├── config/
├── database/migrations/
└── routes/

확장성

테넌트 수 제한이 있나요?

기술적 제한 없음. 실제 제한은 인프라 성능에 따름.

규모테넌트 수권장 인프라
소규모~100단일 서버
중규모~1,000로드밸런서 + 복제
대규모~10,000+샤딩 + 클러스터

대용량 트래픽 처리 가능한가요?

가능합니다. 확장 전략:

  1. 수평 확장

    • 웹 서버: 로드밸런서 뒤 다중 인스턴스
    • DB: Read Replica
    • 캐시: Redis Cluster
  2. 성능 최적화

    • Query 캐싱
    • Eager Loading
    • Queue 활용
  3. 인프라 확장

    • CDN (정적 자산)
    • 오토스케일링 (AWS, GCP)

마이크로서비스로 전환 가능한가요?

모놀리식 시작, 점진적 분리 가능:

현재 (모놀리식)
┌─────────────────────┐
│ Laravel Application │
│ ├── Auth │
│ ├── Users │
│ └── Billing │
└─────────────────────┘

미래 (마이크로서비스)
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Auth API │ │ User API │ │ Billing │
└──────────┘ └──────────┘ └──────────┘

분리 시 고려사항:

  • API Gateway 도입
  • 이벤트 기반 통신 (RabbitMQ, Kafka)
  • 분산 트랜잭션 처리

커스터마이징

UI를 변경할 수 있나요?

네, Filament 기반으로 커스터마이징 가능:

// 테마 변경
// config/filament.php
'theme' => [
'colors' => [
'primary' => Color::Blue,
],
],

// 컴포넌트 오버라이드
// app/Filament/Resources/UserResource.php

변경 가능 항목:

  • 색상, 폰트, 레이아웃
  • 메뉴 구조
  • 커스텀 페이지/위젯
  • 다국어 텍스트

인증 방식을 변경할 수 있나요?

기본 제공:

  • Email + Password
  • Laravel Sanctum (API Token)

플러그인으로 추가:

  • Two-Factor Authentication (2FA)
  • Social Login (OAuth)
  • SSO (SAML)

커스텀 구현:

// app/Providers/AuthServiceProvider.php에서 확장
Auth::extend('custom', function ($app, $name, array $config) {
return new CustomGuard(Auth::createUserProvider($config['provider']));
});

데이터베이스 스키마를 변경해도 되나요?

네, 단 규칙을 따라야 합니다:

가능:

  • 새 테이블 추가
  • 새 컬럼 추가
  • 커스텀 마이그레이션

⚠️ 주의:

  • Core 테이블 구조 변경 (업그레이드 시 충돌 가능)
  • tenant_id 컬럼 제거 (RLS 깨짐)
# 커스텀 마이그레이션
php artisan make:migration add_custom_field_to_users

성능

예상 응답 시간은?

작업목표최적화
API 응답< 200ms캐싱
페이지 로드< 1sCDN, 캐싱
DB 쿼리< 50ms인덱스
인증< 100ms세션 캐싱

권장 서버 스펙은?

규모CPURAMStorage
개발2 Core4GB20GB SSD
소규모4 Core8GB50GB SSD
중규모8 Core16GB100GB SSD
대규모16+ Core32GB+500GB+ SSD

캐싱 전략은?

// 레이어별 캐싱

// 1. 설정 캐싱
php artisan config:cache
php artisan route:cache
php artisan view:cache

// 2. 쿼리 캐싱
Cache::remember('users:tenant:1', 3600, fn() =>
User::where('tenant_id', 1)->get()
);

// 3. HTTP 캐싱
return response()->json($data)
->header('Cache-Control', 'public, max-age=3600');

보안

어떤 보안 기능이 있나요?

기능구현
인증Laravel Sanctum
권한Level 0~6 계층 RBAC + Policy
데이터 격리PostgreSQL RLS
암호화bcrypt (비밀번호), AES-256 (데이터)
CSRFLaravel 기본
XSSBlade 자동 이스케이프
SQL InjectionEloquent ORM

보안 감사를 통과했나요?

내부 보안 검토 완료:

  • OWASP Top 10 대응
  • 코드 리뷰
  • 자동화된 보안 스캔

권장:

  • 프로덕션 전 전문 보안 감사
  • 정기 취약점 스캔
  • 버그 바운티 프로그램

GDPR/개인정보 처리는?

지원 기능:

  • 데이터 내보내기 API
  • 계정 삭제 기능
  • 감사 로그 (Audit)
  • 동의 관리 (플러그인)

구현 필요:

  • 개인정보 처리방침
  • 쿠키 동의 배너
  • DPO 지정 (해당 시)

배포

권장 배포 방식은?

방식난이도확장성비용
Docker Compose쉬움중간낮음
Kubernetes어려움높음중간
Laravel Vapor쉬움높음중간
전통적 (VPS)중간낮음낮음

추천: 시작은 Docker Compose, 성장 후 Kubernetes


CI/CD는 어떻게 구성하나요?

GitHub Actions 예시:

# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: |
composer install --no-dev
npm ci && npm run build
- name: Test
run: php artisan test
- name: Deploy
run: ./deploy.sh

무중단 배포 가능한가요?

가능합니다:

# Envoy.blade.php
@task('deploy')
cd /var/www/app
git pull origin main
composer install --no-dev
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan queue:restart
@endtask

Blue-Green 배포:

  • 두 환경 준비 (Blue, Green)
  • 새 버전을 대기 환경에 배포
  • 로드밸런서로 전환

관련 문서