# MNG 환경 구성 가이드 ## 📋 개요 MNG 프로젝트를 위한 Docker 환경 구성 가이드입니다. 기존 SAM 프로젝트 (api, admin, react)에 mng 서비스를 추가합니다. --- ## 🎯 목표 환경 ``` SAM/ ├── api/ (api.sam.kr) - 외부 API ├── admin/ (admin.sam.kr) - Filament 관리자 (deprecated) ├── react/ (dev.sam.kr) - React 프론트엔드 ├── mng/ (mng.sam.kr) - 새 관리자 패널 ⭐ NEW └── docker/ ├── docker-compose.yml ├── nginx/nginx.conf └── mng/ ⭐ NEW ├── Dockerfile ├── nginx.conf └── supervisord.conf ``` ### 도메인 구성 | 도메인 | 서비스 | 용도 | |--------|--------|------| | api.sam.kr | api | 외부 클라이언트 API | | admin.sam.kr | admin | Filament 관리자 (점차 폐기) | | dev.sam.kr | react | React 프론트엔드 | | **mng.sam.kr** | **mng** | **새 관리자 패널** ⭐ | --- ## 📐 Phase 0: 환경 구성 (최초 1회) ### Step 1: Laravel 프로젝트 생성 ```bash # SAM 디렉토리로 이동 cd /Users/hskwon/Works/@KD_SAM/SAM # Laravel 12 프로젝트 생성 composer create-project laravel/laravel mng cd mng # 필수 패키지 설치 composer require laravel/sanctum composer require darkaonline/l5-swagger composer require --dev laravel/pint # NPM 패키지 설치 npm install -D tailwindcss daisyui @tailwindcss/forms postcss autoprefixer npm install htmx.org npx tailwindcss init -p ``` ### Step 2: 환경 변수 설정 **mng/.env** (기본값 수정) ```env APP_NAME=MNG APP_ENV=local APP_KEY=base64:... (자동 생성됨) APP_DEBUG=true APP_URL=http://mng.sam.kr DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=samdb DB_USERNAME=samuser DB_PASSWORD=sampass CACHE_DRIVER=file QUEUE_CONNECTION=sync SESSION_DRIVER=file SANCTUM_STATEFUL_DOMAINS=mng.sam.kr # 이메일 설정 (Gmail SMTP) MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=your-email@gmail.com MAIL_PASSWORD=your-app-password MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=your-email@gmail.com MAIL_FROM_NAME="${APP_NAME}" ``` ### 이메일 설정 (Gmail SMTP) 사용자 등록 시 임시 비밀번호 발송, 비밀번호 초기화 등 이메일 기능을 사용하려면 SMTP 설정이 필요합니다. **Gmail 앱 비밀번호 발급:** 1. Google 계정 → 보안 → 2단계 인증 활성화 2. 앱 비밀번호 생성 (https://myaccount.google.com/apppasswords) 3. 생성된 16자리 비밀번호를 `MAIL_PASSWORD`에 입력 **Google Groups 이메일 사용 (발신자 변경):** - Google Groups 이메일(예: `develop@company.com`)을 발신자로 사용하려면: 1. Gmail 설정 → 계정 및 가져오기 → 다른 주소에서 메일 보내기 2. 그룹 이메일 주소 추가 및 인증 3. `.env`의 `MAIL_FROM_ADDRESS`를 그룹 이메일로 설정 **주의사항:** - `MAIL_USERNAME`은 실제 Gmail 계정 (SMTP 인증용) - `MAIL_FROM_ADDRESS`는 발신자 표시 주소 (Gmail에서 "다른 주소에서 메일 보내기" 설정 필요) - 앱 비밀번호는 일반 비밀번호가 아닌 Google에서 생성한 16자리 코드 ### Step 3: Tailwind + DaisyUI 설정 **mng/tailwind.config.js** ```js /** @type {import('tailwindcss').Config} */ export default { content: [ "./resources/**/*.blade.php", "./resources/**/*.js", "./resources/**/*.vue", ], theme: { extend: {}, }, plugins: [ require('daisyui'), require('@tailwindcss/forms'), ], daisyui: { themes: ['light', 'dark'], }, } ``` **mng/resources/css/app.css** ```css @tailwind base; @tailwind components; @tailwind utilities; ``` **mng/resources/js/app.js** ```js import './bootstrap'; import htmx from 'htmx.org'; window.htmx = htmx; // HTMX 전역 설정 document.addEventListener('DOMContentLoaded', () => { // CSRF 토큰 자동 추가 document.body.addEventListener('htmx:configRequest', (event) => { event.detail.headers['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').content; }); // 에러 처리 document.body.addEventListener('htmx:responseError', (event) => { console.error('HTMX Error:', event.detail); alert('오류가 발생했습니다. 다시 시도해주세요.'); }); }); ``` **mng/vite.config.js** (확인) ```js import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; export default defineConfig({ plugins: [ laravel({ input: ['resources/css/app.css', 'resources/js/app.js'], refresh: true, }), ], }); ``` ### Step 4: Docker 설정 파일 생성 #### 4-1. Dockerfile 생성 **docker/mng/Dockerfile** ```dockerfile FROM php:8.4-fpm # 시스템 패키지 설치 RUN apt-get update && apt-get install -y \ git \ curl \ libpng-dev \ libonig-dev \ libxml2-dev \ libzip-dev \ zip \ unzip \ supervisor \ nginx # PHP 확장 설치 RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip # Composer 설치 COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # Node.js 설치 (Vite 빌드용) RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y nodejs # 작업 디렉토리 설정 WORKDIR /var/www/mng # 권한 설정 RUN chown -R www-data:www-data /var/www/mng # PHP-FPM 포트 노출 EXPOSE 9000 CMD ["php-fpm"] ``` #### 4-2. Nginx 설정 (PHP-FPM 연동) **docker/mng/nginx.conf** ```nginx server { listen 9000; server_name localhost; root /var/www/mng/public; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } ``` #### 4-3. Supervisor 설정 (선택) **docker/mng/supervisord.conf** ```ini [supervisord] nodaemon=true [program:php-fpm] command=/usr/local/sbin/php-fpm autostart=true autorestart=true stderr_logfile=/var/log/php-fpm.err.log stdout_logfile=/var/log/php-fpm.out.log ``` #### 4-4. PHP 업로드 설정 **docker/mng/uploads.ini** ```ini upload_max_filesize = 100M post_max_size = 100M max_execution_time = 300 memory_limit = 256M ``` ### Step 5: docker-compose.yml 업데이트 **docker/docker-compose.yml** (mng 서비스 추가) ```yaml services: nginx: image: nginx:latest ports: - "80:80" volumes: - ../api:/var/www/api - ../admin:/var/www/admin - ../mng:/var/www/mng # ⭐ NEW - ../docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - api - admin - mng # ⭐ NEW - react networks: - samnet api: build: context: . dockerfile: ../docker/api/Dockerfile volumes: - ../api:/var/www/api - ../docker/api/nginx.conf:/etc/nginx/conf.d/default.conf - ../docker/api/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf - ../docker/api/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini environment: - DB_HOST=mysql - DB_PORT=3306 - DB_DATABASE=samdb - DB_USERNAME=samuser - DB_PASSWORD=sampass networks: - samnet working_dir: /var/www/api admin: build: context: . dockerfile: ../docker/admin/Dockerfile volumes: - ../admin:/var/www/admin - ../docker/admin/nginx.conf:/etc/nginx/conf.d/default.conf - ../docker/admin/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf - ../docker/admin/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini environment: - DB_HOST=mysql - DB_PORT=3306 - DB_DATABASE=samdb - DB_USERNAME=samuser - DB_PASSWORD=sampass networks: - samnet working_dir: /var/www/admin # ⭐ NEW: MNG 서비스 mng: build: context: . dockerfile: ../docker/mng/Dockerfile volumes: - ../mng:/var/www/mng - ../docker/mng/nginx.conf:/etc/nginx/conf.d/default.conf - ../docker/mng/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf - ../docker/mng/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini environment: - DB_HOST=mysql - DB_PORT=3306 - DB_DATABASE=samdb - DB_USERNAME=samuser - DB_PASSWORD=sampass networks: - samnet working_dir: /var/www/mng react: build: context: .. dockerfile: docker/react/Dockerfile volumes: - ../react:/app - /app/node_modules - /app/.next environment: - NEXT_PUBLIC_API_BASE_URL=http://api.sam.kr - NEXT_PUBLIC_ADMIN_URL=http://admin.sam.kr - NEXT_PUBLIC_MNG_URL=http://mng.sam.kr # ⭐ NEW - NEXT_PUBLIC_API_KEY=${NEXT_PUBLIC_API_KEY:-} - NEXT_PUBLIC_APP_NAME=SAM - NODE_ENV=development networks: - samnet working_dir: /app mysql: image: mysql:8.0 restart: always environment: MYSQL_DATABASE: samdb MYSQL_USER: samuser MYSQL_PASSWORD: sampass MYSQL_ROOT_PASSWORD: root volumes: - db_data:/var/lib/mysql - ../docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql ports: - "3306:3306" networks: - samnet volumes: db_data: networks: samnet: driver: bridge ``` ### Step 6: Nginx 메인 설정 업데이트 **docker/nginx/nginx.conf** (mng.sam.kr 서버 블록 추가) ```nginx events {} http { include /etc/nginx/mime.types; default_type application/octet-stream; client_max_body_size 100M; # ... 기존 서버 블록들 (dev.haisa.kr, api.sam.kr, admin.sam.kr, dev.sam.kr) # ⭐ NEW: MNG 서버 블록 server { listen 80; server_name mng.sam.kr; root /var/www/mng/public; index index.php index.html; access_log /var/log/nginx/mng.sam.kr_access.log; error_log /var/log/nginx/mng.sam.kr_error.log; # 🛡️ 보안: 악의적 경로 패턴 차단 if ($request_uri ~* "(\.\.\/|\.\.\\|etc\/passwd|\.env|\.git|\.htaccess|\.sql|@fs\/)") { return 403; } # 🛡️ 보안: 의심스러운 User-Agent 차단 if ($http_user_agent ~* "(sqlmap|nikto|nmap|masscan|metasploit|nessus)") { return 403; } # 정적 자산 처리 location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot|map)$ { try_files $uri =404; access_log off; expires 30d; add_header Cache-Control "public"; } # 일반 요청 처리 location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include fastcgi_params; fastcgi_pass mng:9000; # 서비스명 mng fastcgi_param SCRIPT_FILENAME /var/www/mng/public$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } } ``` ### Step 7: hosts 파일 설정 **/etc/hosts** (로컬 도메인 추가) ```bash # SAM 프로젝트 도메인 127.0.0.1 api.sam.kr 127.0.0.1 admin.sam.kr 127.0.0.1 dev.sam.kr 127.0.0.1 mng.sam.kr # ⭐ NEW ``` **macOS/Linux:** ```bash sudo nano /etc/hosts # 위 내용 추가 후 저장 ``` **Windows:** ``` C:\Windows\System32\drivers\etc\hosts # 관리자 권한으로 메모장 열어서 추가 ``` ### Step 8: admin/ 모델 복사 ```bash cd /Users/hskwon/Works/@KD_SAM/SAM # Models 복사 cp -r admin/app/Models/* mng/app/Models/ # Traits 복사 mkdir -p mng/app/Traits cp admin/app/Traits/BelongsToTenant.php mng/app/Traits/ cp admin/app/Traits/HasAuditLog.php mng/app/Traits/ # Filament 의존성 제거 (수동 작업 필요) # - form(), table(), canAccessPanel() 등 삭제 # - FilamentUser 인터페이스 제거 ``` ### Step 9: Docker 빌드 및 실행 ```bash cd /Users/hskwon/Works/@KD_SAM/SAM/docker # 기존 컨테이너 중지 docker-compose down # mng 서비스 빌드 docker-compose build mng # 전체 서비스 시작 docker-compose up -d # 로그 확인 docker-compose logs -f mng # mng 컨테이너 접속 docker-compose exec mng bash # 컨테이너 내부에서 Laravel 설정 php artisan key:generate php artisan migrate php artisan storage:link # Vite 빌드 (개발 모드) npm run dev # 또는 프로덕션 빌드 npm run build ``` ### Step 10: 동작 확인 ```bash # 1. 브라우저에서 확인 http://mng.sam.kr # 2. API 확인 (예시) curl http://mng.sam.kr/api/admin/health # 3. 로그 확인 docker-compose logs mng ``` --- ## 🔧 문제 해결 ### 1. "502 Bad Gateway" 에러 ```bash # PHP-FPM 상태 확인 docker-compose exec mng ps aux | grep php-fpm # 재시작 docker-compose restart mng ``` ### 2. 권한 에러 ```bash # 컨테이너 내부에서 docker-compose exec mng bash chown -R www-data:www-data /var/www/mng/storage chown -R www-data:www-data /var/www/mng/bootstrap/cache chmod -R 775 /var/www/mng/storage chmod -R 775 /var/www/mng/bootstrap/cache ``` ### 3. DB 연결 실패 ```bash # MySQL 컨테이너 확인 docker-compose exec mysql mysql -u samuser -psampass -e "SHOW DATABASES;" # mng .env 확인 docker-compose exec mng cat .env | grep DB_ ``` ### 4. Vite 빌드 실패 ```bash # 컨테이너 내부에서 docker-compose exec mng bash npm install npm run build ``` ### 5. HTMX 동작 안함 - 브라우저 개발자 도구 → Network 탭 확인 - `HX-Request` 헤더 있는지 확인 - CSRF 토큰 확인 (meta 태그) --- ## 📋 환경 구성 체크리스트 ``` [ ] Step 1: Laravel 프로젝트 생성 (mng/) [ ] Step 2: .env 설정 (DB 정보) [ ] Step 3: Tailwind + DaisyUI 설정 [ ] Step 4: Docker 설정 파일 생성 (Dockerfile, nginx.conf) [ ] Step 5: docker-compose.yml 업데이트 (mng 서비스 추가) [ ] Step 6: Nginx 메인 설정 업데이트 (mng.sam.kr 서버 블록) [ ] Step 7: /etc/hosts 설정 (mng.sam.kr) [ ] Step 8: admin/ 모델 복사 및 Filament 제거 [ ] Step 9: Docker 빌드 및 실행 [ ] Step 10: 동작 확인 (http://mng.sam.kr) ``` --- ## 🚀 다음 단계 환경 구성 완료 후: 1. **Phase 1**: 인증 시스템 구현 (로그인 API + Blade) 2. **Phase 2**: 대시보드 구현 (레이아웃 + HTMX) 3. **Phase 3**: 사용자 관리 (첫 CRUD 기능) DEV_PROCESS.md 문서를 참고하여 개발을 진행하세요. --- **작성일**: 2025-01-20 **버전**: 1.0 **환경**: Docker + Laravel 12 + MySQL 8.0 + HTMX + DaisyUI