# SAM 로컬 개발 환경 셋팅 가이드 > 최종 업데이트: 2026-03-09 --- ## 1. 사전 준비 ### 필수 소프트웨어 | 소프트웨어 | 버전 | 용도 | 설치 | |-----------|------|------|---------------------------------------------------------------| | **Docker Desktop** | 최신 | 컨테이너 실행 | [docker.com](https://www.docker.com/products/docker-desktop/) | | **Git** | 최신 | 버전 관리 | `brew install git` | | **mkcert** | 최신 | 로컬 SSL 인증서 | `brew install mkcert` | | **텍스트 에디터** | - | 코드 편집 | JetBrains IDE 권장 | > Docker Desktop이 설치되면 PHP, Node.js, MySQL 등은 **별도 설치 불필요** (Docker 컨테이너 내부에서 실행) ### Git 서버 정보 | 항목 | 값 | |------|-----| | Git 서버 | Gitea (자체 호스팅) | | 서버 주소 | `http://114.203.209.83:3000` | | 조직 | `SamProject` | > Gitea 계정이 필요합니다. 팀장에게 계정 생성을 요청하세요. --- ## 2. 저장소 클론 ### 디렉토리 구조 ``` Works/@KD_SAM/SAM/ ← 루트 (원하는 경로에 생성) ├── api/ ← Laravel REST API ├── mng/ ← Laravel 관리자 패널 ├── react/ ← Next.js 프론트엔드 ├── docs/ ← 기술 문서 ├── hotfix/ ← 테스트/QA 문서 ├── docker/ ← Docker 설정 (api 저장소에 포함되지 않음) ├── design/ ← 디자인 시스템 (선택) └── planning/ ← 기획 문서 (선택) ``` ### 클론 명령어 ```bash # 작업 디렉토리 생성 mkdir -p ~/Works/@KD_SAM/SAM cd ~/Works/@KD_SAM/SAM # 5개 저장소 클론 git clone http://114.203.209.83:3000/SamProject/sam-api.git api git clone http://114.203.209.83:3000/SamProject/sam-manage.git mng git clone http://114.203.209.83:3000/SamProject/sam-react-prod.git react git clone http://114.203.209.83:3000/SamProject/sam-docs.git docs git clone http://114.203.209.83:3000/SamProject/sam-hotfix.git hotfix ``` ### 기본 브랜치 전환 ```bash # api, react는 develop 브랜치에서 작업 cd api && git checkout develop && cd .. cd react && git checkout develop && cd .. ``` > **중요**: `main` 브랜치에서 직접 작업하지 않습니다. 항상 `develop`에서 작업합니다. --- ## 3. Docker 환경 구성 ### 3-1. Docker 설정 파일 확인 `docker/` 디렉토리에 모든 Docker 설정이 포함되어 있습니다. ``` docker/ ├── docker-compose.yml ← 메인 Compose 파일 ├── .env ← Compose 환경변수 ├── api/ │ ├── Dockerfile ← PHP 8.4 + Nginx │ ├── nginx.conf │ ├── supervisord.conf │ └── uploads.ini ├── mng/ │ ├── Dockerfile ← PHP 8.4 + Nginx │ ├── nginx.conf │ ├── supervisord.conf │ └── uploads.ini ├── react/ │ └── Dockerfile ← Node 20 + Chromium (PDF용) ├── mysql/ │ ├── init.sql ← 초기 DB/유저 생성 │ └── my.cnf ← MySQL 설정 ├── nginx/ │ ├── nginx.conf ← 리버스 프록시 설정 │ └── ssl/ ← SSL 인증서 └── 5130/ └── Dockerfile ← 레거시 PHP 7.3 ``` ### 3-2. 서비스 구성 | 서비스 | 이미지 | 내부 포트 | 역할 | |--------|--------|-----------|------| | **nginx** | nginx:latest | 80, 443 | 리버스 프록시, SSL 종료 | | **api** | PHP 8.4-fpm | 9000 | REST API 백엔드 | | **mng** | PHP 8.4-fpm | 9000 | 관리자 패널 | | **react** | node:20-alpine | 3000 | Next.js 프론트엔드 | | **mysql** | mysql:8.0 | 3306 | 데이터베이스 | | **php73** | PHP 7.3-fpm | 9000 | 레거시 5130 앱 | ### 3-3. 네트워크 모든 컨테이너는 `samnet` 브릿지 네트워크로 연결됩니다. ``` [브라우저] → [nginx:443] → api / mng / react (내부 라우팅) → mysql (컨테이너명: sam-mysql-1) ``` --- ## 4. hosts 파일 설정 로컬 도메인을 사용하기 위해 hosts 파일을 수정합니다. ```bash sudo nano /etc/hosts ``` 아래 내용을 추가: ``` 127.0.0.1 api.sam.kr mng.sam.kr admin.sam.kr dev.sam.kr design.sam.kr plan.sam.kr 5130.sam.kr 127.0.0.1 sam.kr www.sam.kr sales.sam.kr demo.sam.kr ``` --- ## 5. SSL 인증서 설정 로컬 HTTPS를 위한 자체 서명 인증서를 생성합니다. ### 5-1. mkcert 설치 및 초기화 ```bash # mkcert 설치 (처음 한 번) brew install mkcert mkcert -install # 로컬 CA를 시스템에 등록 ``` ### 5-2. 와일드카드 인증서 생성 ```bash cd docker/nginx/ssl/ # *.sam.kr 와일드카드 인증서 생성 mkcert "*.sam.kr" localhost 127.0.0.1 ::1 # 파일명 변경 (nginx.conf에서 참조하는 이름으로) mv _wildcard.sam.kr+3.pem sam.kr.crt mv _wildcard.sam.kr+3-key.pem sam.kr.key ``` ### 5-3. 포트 포워딩 설정 (macOS) Docker가 443 포트를 4443으로 매핑하므로, 브라우저에서 표준 443 포트로 접속하려면 포트 포워딩이 필요합니다. ```bash # pfctl 규칙 적용 (443 → 4443 포워딩) sudo pfctl -ef docker/nginx/ssl/pf-sam.conf ``` > **참고**: macOS 재부팅 시 이 설정은 초기화되므로 재부팅 후 다시 실행해야 합니다. **포트 포워딩 없이 사용하려면** `https://api.sam.kr:4443` 처럼 포트 번호를 직접 지정합니다. --- ## 6. 환경변수 (.env) 설정 ### 6-1. API (.env) ```bash cd api cp .env.example .env ``` `.env` 파일에서 확인/수정할 항목: ```env # 앱 키 생성은 Docker 실행 후 컨테이너 내에서 수행 # docker exec sam-api-1 php artisan key:generate APP_NAME="SAM API" APP_ENV=local APP_DEBUG=true APP_URL=https://api.sam.kr/ # DB (Docker 환경에서는 docker-compose가 오버라이드) DB_HOST=127.0.0.1 # 로컬 직접 접속 시 # DB_HOST=sam-mysql-1 # Docker 환경 (자동 오버라이드) DB_DATABASE=samdb DB_USERNAME=samuser DB_PASSWORD=sampass # Swagger L5_SWAGGER_GENERATE_ALWAYS=true L5_SWAGGER_CONST_HOST=https://api.sam.kr/ # Sanctum 토큰 (분 단위) SANCTUM_ACCESS_TOKEN_EXPIRATION=120 SANCTUM_REFRESH_TOKEN_EXPIRATION=10080 # 내부 통신 키 (MNG ↔ API) INTERNAL_EXCHANGE_SECRET= # 팀 내부 문서에서 확인 ``` > **API 키, Firebase, AI 서비스 키** 등 민감한 값은 팀 내부 문서(노션)에서 별도 공유합니다. ### 6-2. MNG (.env) ```bash cd mng cp .env.example .env ``` ```env APP_NAME=SAM-MNG APP_ENV=local APP_DEBUG=true APP_URL=https://mng.sam.kr DB_HOST=sam-mysql-1 DB_DATABASE=samdb DB_USERNAME=samuser DB_PASSWORD=sampass # API 서버 연동 API_BASE_URL=https://api.sam.kr # 내부 통신 키 (API와 동일한 값) INTERNAL_EXCHANGE_SECRET= # API의 값과 동일하게 설정 ``` ### 6-3. React (.env.local) ```bash cd react cp .env.example .env.local ``` ```env NEXT_PUBLIC_APP_ENV=local NEXT_PUBLIC_API_URL=https://api.sam.kr NEXT_PUBLIC_FRONTEND_URL=https://dev.sam.kr NEXT_PUBLIC_AUTH_MODE=sanctum # API Key (서버 사이드 전용 - NEXT_PUBLIC_ 접두사 붙이지 말 것!) API_KEY= # 팀 내부 문서에서 확인 # 개발 도구 NEXT_PUBLIC_DEV_TOOLBAR_ENABLED=false # Puppeteer (PDF 생성 - Docker에서는 자동 설정) PUPPETEER_EXECUTABLE_PATH=/Applications/Google Chrome.app/Contents/MacOS/Google Chrome ``` ### 6-4. docs / hotfix 별도 환경변수 설정 불필요 (순수 마크다운 문서 저장소) --- ## 7. Docker 실행 ### 7-1. 최초 실행 ```bash cd docker # 이미지 빌드 + 컨테이너 시작 docker compose up -d --build ``` > 첫 실행 시 이미지 빌드에 5~10분 소요될 수 있습니다. ### 7-2. 초기 설정 (최초 1회) ```bash # API: 앱 키 생성 + 의존성 설치 + 마이그레이션 docker exec sam-api-1 php artisan key:generate docker exec sam-api-1 composer install docker exec sam-api-1 php artisan migrate docker exec sam-api-1 php artisan l5-swagger:generate # MNG: 앱 키 생성 + 의존성 설치 docker exec sam-mng-1 php artisan key:generate docker exec sam-mng-1 composer install docker exec sam-mng-1 npm install docker exec sam-mng-1 npm run build ``` > React는 Docker 컨테이너 시작 시 자동으로 `npm install` + `npm run dev`가 실행됩니다. ### 7-3. 일상적인 시작/종료 ```bash cd docker # 시작 docker compose up -d # 종료 docker compose down # 로그 확인 docker compose logs -f # 전체 docker compose logs -f api # API만 docker compose logs -f react # React만 # 컨테이너 상태 확인 docker compose ps ``` --- ## 8. 접속 확인 ### 8-1. 로컬 도메인 | 서비스 | URL | 설명 | |--------|-----|------| | **프론트엔드** | `https://dev.sam.kr` | Next.js 사용자 화면 | | **API 문서** | `https://api.sam.kr/api-docs/index.html` | Swagger UI | | **관리자 패널** | `https://mng.sam.kr` | MNG 관리자 화면 | | **관리자 (별칭)** | `https://admin.sam.kr` | MNG와 동일 | | **디자인 시스템** | `https://design.sam.kr` | 컴포넌트 스토리북 | | **레거시** | `https://5130.sam.kr` | 기존 PHP 시스템 | ### 8-2. DB 접속 정보 | 항목 | 값 | |------|-----| | Host | `127.0.0.1` | | Port | `3306` | | Database | `samdb` | | Username | `samuser` | | Password | `sampass` | | Root Password | `root` | | 레거시 DB | `chandj` | > DBeaver, DataGrip, MySQL Workbench 등 원하는 DB 클라이언트로 접속 가능 ### 8-3. 접속 테스트 ```bash # API 응답 확인 curl -k https://api.sam.kr/api-docs/index.html # MySQL 접속 확인 docker exec sam-mysql-1 mysql -u samuser -psampass -e "SHOW DATABASES;" ``` --- ## 9. 저장소별 상세 정보 ### 9-1. api/ (REST API 서버) | 항목 | 값 | |------|-----| | 프레임워크 | Laravel 12 (PHP 8.4) | | 인증 | Sanctum (토큰 기반) | | API 문서 | Swagger (l5-swagger) | | DB | MySQL 8.0 (samdb) | | 역할 | 모든 비즈니스 로직의 중심, 프론트/관리자 모두 이 API 사용 | **주요 명령어:** ```bash # 컨테이너 진입 docker exec -it sam-api-1 bash # 마이그레이션 php artisan migrate php artisan migrate:status # Swagger 재생성 php artisan l5-swagger:generate # 코드 포매터 ./vendor/bin/pint # 캐시 초기화 php artisan cache:clear php artisan config:clear php artisan route:clear ``` **핵심 디렉토리:** ``` api/ ├── app/ │ ├── Http/Controllers/Api/V1/ ← API 컨트롤러 │ ├── Http/Requests/ ← FormRequest (검증) │ ├── Models/ ← Eloquent 모델 │ ├── Services/ ← 비즈니스 로직 (핵심) │ ├── Swagger/v1/ ← Swagger 문서 클래스 │ └── Helpers/ApiResponse.php ← 응답 헬퍼 ├── database/migrations/ ← DB 마이그레이션 ├── routes/api.php ← API 라우트 └── lang/ko/ ← 한국어 메시지 ``` ### 9-2. mng/ (관리자 패널) | 항목 | 값 | |------|-----| | 프레임워크 | Laravel 12 (PHP 8.4) | | 프론트엔드 | Blade + Tailwind CSS + HTMX + DaisyUI | | 역할 | 시스템 관리, 메뉴/권한 관리, 테넌트 관리 | **주요 명령어:** ```bash # 컨테이너 진입 docker exec -it sam-mng-1 bash # 프론트 에셋 빌드 npm run build # 프로덕션 npm run dev # 개발 (HMR) # 코드 포매터 ./vendor/bin/pint ``` **핵심 디렉토리:** ``` mng/ ├── app/ │ ├── Http/Controllers/ ← 웹 컨트롤러 │ ├── Models/ ← 독립 모델 (API와 별개) │ └── Services/ ← 비즈니스 로직 ├── resources/views/ ← Blade 템플릿 ├── routes/web.php ← 웹 라우트 └── public/ ← 정적 파일 ``` > **주의**: MNG에서는 DB 마이그레이션을 생성/실행하지 않습니다. DB 변경은 반드시 API 프로젝트에서 수행합니다. ### 9-3. react/ (Next.js 프론트엔드) | 항목 | 값 | |------|-----| | 프레임워크 | Next.js 15 (React 19, TypeScript) | | 스타일링 | Tailwind CSS 4 | | UI 라이브러리 | shadcn/ui (Radix UI 기반) | | 상태관리 | Zustand | | 폼 검증 | Zod + React Hook Form | | 역할 | 사용자용 ERP 프론트엔드 | **주요 명령어:** ```bash # React는 Docker 컨테이너가 자동으로 dev 서버를 실행합니다. # 수동 실행이 필요한 경우: docker exec -it sam-react-1 sh npm run dev # 개발 서버 npm run build # 프로덕션 빌드 npm run lint # ESLint ``` **핵심 디렉토리:** ``` react/ ├── src/ │ ├── app/ ← Next.js App Router 페이지 │ ├── components/ │ │ ├── ui/ ← shadcn/ui 원자 컴포넌트 │ │ ├── molecules/ ← 조합 컴포넌트 │ │ ├── organisms/ ← 복합 컴포넌트 │ │ └── [도메인]/ ← 도메인별 컴포넌트 │ ├── lib/ ← 유틸리티, API 헬퍼 │ └── stores/ ← Zustand 스토어 ├── public/ ← 정적 파일 └── next.config.ts ← Next.js 설정 ``` **핵심 규칙:** - 모든 페이지는 `'use client'` 선언 필수 (폐쇄형 ERP, SSR 불필요) - API 호출은 Server Action을 통해 수행 (HttpOnly 쿠키 프록시) - `buildApiUrl()` 유틸리티 필수 사용 ### 9-4. docs/ (기술 문서) | 항목 | 값 | |------|-----| | 내용 | 개발 가이드, API 스펙, 기획 문서, 표준 | | 형식 | Markdown | | 설치 | 없음 (문서만 관리) | ``` docs/ ├── INDEX.md ← 문서 인덱스 (여기부터 시작) ├── dev/ │ ├── dev_plans/ ← 개발 계획 문서 │ ├── standards/ ← 코드/아키텍처 표준 │ ├── guides/ ← 셋업/사용 가이드 │ ├── changes/ ← 변경 로그 │ └── deploys/ ← 배포 문서 ├── features/ ← 기능 스펙 ├── frontend/ ← 프론트엔드 API 스펙 ├── rules/ ← 비즈니스 규칙 └── system/ ← 시스템 아키텍처 ``` ### 9-5. hotfix/ (테스트/QA) | 항목 | 값 | |------|-----| | 내용 | E2E 테스트 결과, 버그 리포트, 테스트 케이스 | | 형식 | Markdown + 스크린샷 | | 설치 | 없음 (문서만 관리) | ``` hotfix/ ├── e2e/ ← E2E 테스트 정의 ├── testcase/ ← 테스트 케이스 문서 ├── reports/ ← 테스트 실행 결과 ├── screenshots/ ← 시각적 테스트 증거 ├── research/ ← 조사 자료 ├── sam.code-workspace ← VS Code 워크스페이스 ├── *-Test-Report_*.md ← 개별 테스트 보고서 └── Fail-*_*.md ← 실패 케이스 보고서 ``` --- ## 10. 주요 아키텍처 개념 ### 10-1. 멀티테넌트 - 모든 데이터에 `tenant_id` 컬럼이 존재 - `BelongsToTenant` 글로벌 스코프가 자동으로 테넌트 필터링 - 하나의 DB에서 여러 회사(테넌트)의 데이터를 격리 ### 10-2. 데이터 흐름 ``` [사용자 브라우저] │ ▼ [Next.js (react/)] ──Server Action──▶ [Laravel API (api/)] ──▶ [MySQL] │ [관리자 브라우저] │ │ │ ▼ │ [Laravel MNG (mng/)] ──내부 API 호출──────────┘ ``` ### 10-3. 인증 방식 | 클라이언트 | 인증 방식 | 설명 | |-----------|----------|------| | React (웹) | Sanctum Cookie | HttpOnly 쿠키, Server Action 프록시 | | MNG (관리자) | 세션 + 내부 HMAC | Laravel 세션 + API 내부 통신 키 | | 외부 연동 | API Key + Bearer | Sanctum 토큰 | --- ## 11. 자주 쓰는 명령어 ### Docker 관련 ```bash # 전체 시작/종료 cd docker && docker compose up -d cd docker && docker compose down # 컨테이너 재시작 docker restart sam-api-1 docker restart sam-react-1 # 이미지 재빌드 (Dockerfile 수정 후) docker compose build --no-cache api docker compose up -d api # 볼륨 포함 완전 초기화 (⚠️ DB 데이터 삭제됨) docker compose down -v ``` ### API 개발 ```bash docker exec sam-api-1 php artisan migrate # 마이그레이션 docker exec sam-api-1 php artisan migrate:rollback # 롤백 docker exec sam-api-1 php artisan l5-swagger:generate # Swagger 재생성 docker exec sam-api-1 ./vendor/bin/pint # 코드 포매팅 docker exec sam-api-1 php artisan tinker # REPL docker exec sam-api-1 php artisan route:list # 라우트 목록 ``` ### MNG 개발 ```bash docker exec sam-mng-1 php artisan tinker docker exec sam-mng-1 npm run dev # Vite HMR docker exec sam-mng-1 npm run build # 에셋 빌드 docker exec sam-mng-1 ./vendor/bin/pint ``` ### MySQL 접속 ```bash # CLI 접속 docker exec -it sam-mysql-1 mysql -u samuser -psampass samdb # 특정 쿼리 실행 docker exec sam-mysql-1 mysql -u samuser -psampass samdb -e "SHOW TABLES;" ``` --- ## 12. 트러블슈팅 ### SSL 인증서 오류 (브라우저에서 "안전하지 않음") ```bash # mkcert CA가 설치되지 않은 경우 mkcert -install # 인증서 재생성 cd docker/nginx/ssl mkcert "*.sam.kr" localhost 127.0.0.1 ::1 mv _wildcard.sam.kr+3.pem sam.kr.crt mv _wildcard.sam.kr+3-key.pem sam.kr.key # Nginx 재시작 docker restart sam-nginx-1 ``` ### 도메인 접속이 안 될 때 ```bash # hosts 파일 확인 cat /etc/hosts | grep sam # DNS 캐시 초기화 (macOS) sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder # Nginx 설정 유효성 확인 docker exec sam-nginx-1 nginx -t ``` ### 포트 포워딩 확인 (443 → 4443) ```bash # 현재 규칙 확인 sudo pfctl -s rules | grep 4443 # 규칙 재적용 sudo pfctl -ef docker/nginx/ssl/pf-sam.conf # 규칙 비활성화 (필요 시) sudo pfctl -d ``` ### DB 접속 오류 ```bash # MySQL 컨테이너 상태 확인 docker compose ps mysql # MySQL 로그 확인 docker compose logs mysql # 수동 접속 테스트 docker exec sam-mysql-1 mysql -u root -proot -e "SELECT 1;" ``` ### React 빌드/HMR 오류 ```bash # node_modules 초기화 docker exec sam-react-1 rm -rf node_modules .next docker exec sam-react-1 npm install docker restart sam-react-1 ``` ### composer/npm 의존성 문제 ```bash # API docker exec sam-api-1 composer install --no-cache docker exec sam-api-1 composer dump-autoload # MNG docker exec sam-mng-1 composer install --no-cache docker exec sam-mng-1 npm ci ``` --- ## 13. Git 워크플로우 ### 브랜치 전략 | 브랜치 | 역할 | 규칙 | |--------|------|------| | `main` | 배포용 | squash merge로만 올림, 직접 커밋 금지 | | `develop` | 일상 작업 | 자유롭게 커밋 | | `feature/*` | 대형 기능 | 선택적 사용 (1주일+ 작업) | ### 커밋 메시지 형식 ``` type: 간결한 설명 type 종류: feat: 새 기능 fix: 버그 수정 refactor: 리팩토링 docs: 문서 chore: 설정, 빌드 style: 코드 포매팅 ``` ### 일상 워크플로우 ```bash # 1. 작업 시작 cd api git checkout develop git pull origin develop # 2. 작업 수행 + 커밋 git add <파일들> git commit -m "feat: 수주관리 삭제 기능 추가" # 3. 푸시 git push origin develop ``` --- ## 14. 셋팅 체크리스트 아래 항목을 순서대로 확인하며 셋팅을 완료합니다. - [ ] Docker Desktop 설치 및 실행 - [ ] Git 설치 및 Gitea 계정 발급 - [ ] 5개 저장소 클론 완료 - [ ] `/etc/hosts` 파일 수정 - [ ] mkcert 설치 + SSL 인증서 생성 - [ ] pfctl 포트 포워딩 설정 - [ ] api/.env 설정 (`.env.example` → `.env`) - [ ] mng/.env 설정 - [ ] react/.env.local 설정 - [ ] API Key, HMAC Key 등 민감 값 입력 (팀 공유 문서 참조) - [ ] `docker compose up -d --build` 실행 - [ ] 초기 설정 실행 (key:generate, composer install, migrate) - [ ] `https://api.sam.kr/api-docs/index.html` 접속 확인 - [ ] `https://mng.sam.kr` 접속 확인 - [ ] `https://dev.sam.kr` 접속 확인 - [ ] DB 클라이언트로 `127.0.0.1:3306` 접속 확인 --- ## 15. 참고 문서 | 문서 | 경로 | 설명 | |------|------|------| | 문서 인덱스 | `docs/INDEX.md` | 전체 문서 목록 | | API 규칙 | `API_RULES.md` | API 개발 규칙 | | 개발 명령어 | `DEV_COMMANDS.md` | 자주 쓰는 명령어 모음 | | 품질 체크리스트 | `QUALITY_CHECKLIST.md` | 코드 품질 체크 항목 | | 빠른 참조 | `SAM_QUICK_REFERENCE.md` | 핵심 규칙 요약 | | SSL 가이드 | `docker/nginx/ssl/SSL_SETUP_GUIDE.md` | SSL 상세 설정 | --- > 문의사항은 팀 슬랙 채널 또는 팀장에게 문의하세요.