Files
sam-manage/docs/SETUP_GUIDE.md
hskwon ea7498ae96 docs: 이메일 설정 가이드 및 작업 이력 업데이트
- SETUP_GUIDE.md: Gmail SMTP 설정 방법, Google Groups 발신자 설정 추가
- CURRENT_WORKS.md: 2025-12-01 비밀번호 자동 생성/이메일 발송 작업 이력
- INDEX.md: 작업 이력 및 최종 업데이트일 갱신
2025-12-01 11:07:58 +09:00

14 KiB

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 프로젝트 생성

# 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 (기본값 수정)

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. .envMAIL_FROM_ADDRESS를 그룹 이메일로 설정

주의사항:

  • MAIL_USERNAME은 실제 Gmail 계정 (SMTP 인증용)
  • MAIL_FROM_ADDRESS는 발신자 표시 주소 (Gmail에서 "다른 주소에서 메일 보내기" 설정 필요)
  • 앱 비밀번호는 일반 비밀번호가 아닌 Google에서 생성한 16자리 코드

Step 3: Tailwind + DaisyUI 설정

mng/tailwind.config.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

@tailwind base;
@tailwind components;
@tailwind utilities;

mng/resources/js/app.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 (확인)

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

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

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

[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

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 서비스 추가)

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 서버 블록 추가)

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 (로컬 도메인 추가)

# 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:

sudo nano /etc/hosts
# 위 내용 추가 후 저장

Windows:

C:\Windows\System32\drivers\etc\hosts
# 관리자 권한으로 메모장 열어서 추가

Step 8: admin/ 모델 복사

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 빌드 및 실행

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: 동작 확인

# 1. 브라우저에서 확인
http://mng.sam.kr

# 2. API 확인 (예시)
curl http://mng.sam.kr/api/admin/health

# 3. 로그 확인
docker-compose logs mng

🔧 문제 해결

1. "502 Bad Gateway" 에러

# PHP-FPM 상태 확인
docker-compose exec mng ps aux | grep php-fpm

# 재시작
docker-compose restart mng

2. 권한 에러

# 컨테이너 내부에서
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 연결 실패

# MySQL 컨테이너 확인
docker-compose exec mysql mysql -u samuser -psampass -e "SHOW DATABASES;"

# mng .env 확인
docker-compose exec mng cat .env | grep DB_

4. Vite 빌드 실패

# 컨테이너 내부에서
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