멀티 프로젝트 구조
이 문서는 검토 중입니다. 내용이 변경될 수 있습니다.
Multi-SaaS Kit은 하나의 코드베이스에서 여러 SaaS 프로젝트를 관리하는 구조를 제공합니다.
핵심 개념
왜 멀티 프로젝트인가?
SaaS 플랫폼을 운영하다 보면 다양한 고객사나 비즈니스 도메인을 위한 별도 프로젝트가 필요합니다.
| 상황 | 예시 |
|---|---|
| 다른 고객사 | A사용 SaaS, B사용 SaaS |
| 다른 도메인 | 교육용, 의료용, 금융용 |
| 다른 환경 | 개발용, 스테이징, 프로덕션 |
| 특수 목적 | 문서 사이트, 관리 도구 |
Multi-SaaS Kit은 이러한 여러 프로젝트를 단일 리포지토리에서 관리하면서도 완전한 독립성을 보장합니다.
3가지 핵심 원칙
| 원칙 | 설명 |
|---|---|
| 완전 독립 | 각 프로젝트는 자체 DB, Redis, 환경변수를 가짐 |
| 템플릿 복사 | 새 프로젝트는 _template 복사로 시작 |
| 소스/데이터 분리 | 소스 코드와 런타임 데이터를 물리적으로 분리 |
전체 폴더 구조
multi-saas-kit/
├── Makefile # 플랫폼 명령어 (프로젝트 생성, 배포 등)
├── .env # 플랫폼 레벨 환경변수
│
├── ops/ # 운영 스크립트
│ └── scripts/
│ ├── create-project.sh # 프로젝트 생성
│ └── release.sh # 릴리즈 스냅샷 생성
│
├── packages/ # Core + Plugins (Monorepo)
│ ├── core/ # Core 모듈 (중앙 관리)
│ └── plugins/ # 플러그인 (수익화 대상)
│
├── workspace/ # ⭐ 개발 소스 (Git 관리)
│ ├── _docs/ # 플랫폼 문서
│ ├── _template/ # 프로젝트 템플릿
│ ├── _devtools/ # 개발 도구 (dashboard, pgadmin)
│ ├── _portal/ # 비즈니스 플랫폼 (web, plugin-store)
│ └── {project}/ # 실제 프로젝트
│
├── data/ # 런타임 데이터 (Git 제외)
│ ├── platform/ # 플랫폼 레벨 데이터
│ └── projects/{project}/ # 프로젝트별 DB/Redis 데이터
│
├── releases/ # 릴리즈 스냅샷 (Git 제외)
│
├── live/ # 프로덕션 심볼릭 링크 (Git 제외)
│
└── backups/ # 백업 데이터 (Git 제외)
폴더 명명 규칙
언더스코어 접두사 (_)
Multi-SaaS Kit은 언더스코어 접두사로 특수 폴더와 일반 프로젝트를 구분합니다.
| 접두사 | 의미 | 예시 |
|---|---|---|
_ (있음) | 특수 폴더 (프로젝트 아님) | _template, _docs, _devtools, _portal |
| 없음 | 실제 프로젝트 | myapp, client-portal, quant.how |
workspace/ 내부 구조
workspace/
├── _template/ # 특수: 새 프로젝트 템플릿
├── _docs/ # 특수: 플랫폼 문서
├── _devtools/ # 특수: 개발자 도구
├── _portal/ # 특수: 비즈니스 플랫폼
├── _security/ # 특수: 보안 도구
│
├── myapp/ # 실제 프로젝트
├── client-portal/ # 실제 프로젝트
└── quant.how/ # 실제 프로젝트
프로젝트 내부 구조
workspace/{project}/
├── .env # 환경변수 (Git 제외)
├── .env.example # 환경변수 템플릿
├── CLAUDE.md # AI 지침
│
├── _docker/ # 특수: Docker 설정
│ ├── docker-compose.amd64.yml # AMD64/x86_64
│ ├── docker-compose.arm64.yml # ARM64 (Apple Silicon)
│ └── conf/
│ ├── nginx/
│ ├── php/
│ ├── postgres/
│ └── redis/
│
├── docs/ # 프로젝트 문서
│ ├── design/
│ ├── discussion/
│ └── specs/
│
└── web/ # Laravel 애플리케이션
├── app/
│ └── Core → packages/core # 심볼릭 링크
└── ...
특수 폴더 설명
_template
새 프로젝트를 위한 템플릿입니다. make create NAME=myapp 명령으로 이 폴더를 복사하여 새 프로젝트를 생성합니다.
_template/
├── .env.example # 환경변수 템플릿
├── _docker/ # Docker 설정
│ ├── docker-compose.amd64.yml
│ ├── docker-compose.arm64.yml
│ └── conf/ # 서비스별 설정
│
├── docs/ # 문서 구조 템플릿
│
└── web/ # Laravel 애플리케이션
├── app/
│ ├── Core → packages/core # Core 모듈
│ └── Plugins → packages/plugins # 플러그인
└── ...
_template은 계속 발전합니다. 새 기능이 추가되면 템플릿에 반영되고, 이후 생성되는 프로젝트는 자동으로 새 기능을 포함합니다.
_devtools
개발자 도구 모음입니다.
| 서비스 | 설명 | 포트 |
|---|---|---|
dashboard | AI 워크플로 시각화 | 8190 |
pgadmin | PostgreSQL 통합 관리 | 5050 |
_portal
비즈니스 플랫폼입니다. Multi-SaaS Kit 제품의 홍보, 판매, 문서 사이트입니다.
| 서비스 | 설명 | 포트 |
|---|---|---|
web | 메인 사이트 (제품 소개, 판매) | 8210 |
web-manual | 문서 사이트 (이 문서!) | 8230 |
plugin-store | 플러그인 스토어 | 8220 |
프로젝트 완전 독립 원칙
각 프로젝트는 모든 요소를 자체 보유합니다.
| 요소 | 위치 | 공유 여부 |
|---|---|---|
| Docker 설정 | {project}/_docker/ | 독립 |
| 환경변수 | {project}/.env | 독립 |
| PostgreSQL | data/projects/{project}/postgres/ | 독립 |
| Redis | data/projects/{project}/redis/ | 독립 |
| 문서 | {project}/docs/ | 독립 |
독립의 장점
- 격리된 환경: 한 프로젝트의 문제가 다른 프로젝트에 영향 없음
- 독립 배포: 프로젝트별로 개별 배포 가능
- 맞춤 설정: 프로젝트별 다른 환경 설정 가능
- 데이터 안전: 프로젝트 간 데이터 완전 분리
유일한 공유: Core 모듈
Core 모듈만 packages/core/에서 중앙 관리되며, 각 프로젝트에서 심볼릭 링크로 참조합니다.
# 심볼릭 링크 구조
workspace/myapp/web/app/Core → ../../../packages/core
workspace/myapp/web/app/Plugins → ../../../packages/plugins
Core 모듈 업데이트는 모든 프로젝트에 즉시 반영됩니다.
소스와 데이터 분리
개발 소스와 런타임 데이터를 물리적으로 분리합니다.
| 유형 | 위치 | Git 관리 |
|---|---|---|
| 소스 코드 | workspace/{project}/ | ✅ 관리 |
| DB 데이터 | data/projects/{project}/postgres/ | ❌ 제외 |
| Redis 데이터 | data/projects/{project}/redis/ | ❌ 제외 |
분리의 장점
# 릴리즈 스냅샷 생성 시
workspace/myapp/ → releases/myapp/251216-1200/
(소스만 복사) (데이터 미포함, 가볍고 빠름)
# 데이터는 별도 위치에서 지속
data/projects/myapp/postgres/ ← 릴리즈와 무관하게 유지
data/projects/myapp/redis/ ← 릴리즈와 무관하게 유지
- 빠른 릴리즈: 데이터 없이 소스만 복사하므로 빠름
- 안전한 롤백: 데이터 영향 없이 코드만 롤백
- 간편한 백업: 데이터 백업은
data/폴더만 대상
프로젝트 생성
make create 명령
# 새 프로젝트 생성
make create NAME=myapp
이 명령은 다음을 수행합니다:
_template→workspace/myapp복사.env.example→.env복사- 보안 값 자동 생성 (DB 비밀번호, 관리자 비밀번호, 경로 난독화)
생성 후 구조
workspace/myapp/
├── .env # 자동 생성된 환경변수
├── .env.example
├── CLAUDE.md
├── _docker/
│ ├── docker-compose.amd64.yml
│ ├── docker-compose.arm64.yml
│ └── conf/
├── docs/
└── web/
필수 설정
# .env 편집
vi workspace/myapp/.env
| 설정 | 기본값 | 변경 필요 |
|---|---|---|
APP_PORT | 8180 | ✅ 포트 충돌 확인 |
DB_PORT | 5433 | ✅ 포트 충돌 확인 |
REDIS_PORT | 6380 | ✅ 포트 충돌 확인 |
PLATFORM_ADMIN_EMAIL | [email protected] | ✅ 실제 이메일로 변경 |
프로젝트 운영
기본 명령어
모든 명령어는 루트 디렉토리에서 NAME 파라미터로 실행합니다.
# 컨테이너 시작
make up NAME=myapp
# 컨테이너 중지
make down NAME=myapp
# 상태 확인
make status NAME=myapp
# 로그 보기
make logs NAME=myapp
# 컨테이너 쉘 접속
make shell NAME=myapp
개발 모드 vs 운영 모드
| 모드 | 조건 | 소스 위치 |
|---|---|---|
| 개발 모드 | live/myapp 없음 | workspace/myapp 직접 사용 |
| 운영 모드 | live/myapp 있음 | releases/myapp/{timestamp} 사용 |
# 개발 모드 → 운영 모드 전환
make live NAME=myapp # releases에 스냅샷 생성 + live 링크
# 운영 모드에서 새 릴리즈 적용
make live NAME=myapp # 새 스냅샷 생성 + live 링크 업데이트
여러 프로젝트 동시 운영
포트 할당
여러 프로젝트를 동시에 실행하려면 포트가 겹치지 않아야 합니다.
| 서비스 | 프로젝트 A | 프로젝 트 B | 프로젝트 C |
|---|---|---|---|
| HTTP | 8100 | 8110 | 8120 |
| PostgreSQL | 5433 | 5434 | 5435 |
| Redis | 6380 | 6381 | 6382 |
같은 포트를 사용하는 프로젝트는 동시에 실행할 수 없습니다. .env에서 포트를 반드시 확인하세요.
포트 할당표
자세한 포트 할당은 포트 할당표를 참조하세요.
Git 관리 규칙
| 폴더 | Git 관리 | 설명 |
|---|---|---|
workspace/ | ✅ | 소스 코드 |
ops/ | ✅ | 운영 스크립트 |
packages/ | ✅ | Core + Plugins |
data/ | ❌ | 런타임 데이터 |
releases/ | ❌ | 릴리즈 스냅샷 |
live/ | ❌ | 프로덕션 링크 |
backups/ | ❌ | 백업 데이터 |
.gitignore 주요 설정
# 런타임 데이터
data/platform/*/
data/projects/*/
# 환경파일 (프로젝트별)
workspace/*/.env
!workspace/*/.env.example
# 릴리즈/배포
releases/*/
live/*/
관련 문서
- Monorepo 접근법 - Core/Plugins 중앙 관리
- 프로젝트 관리 - Makefile 명령어
- Docker 설정 - 컨테이너 구성
- 첫 프로젝트 생성 - 실습 튜토리얼