Files
sam-docs/guides/server-how-it-works.md
권혁성 0ace50b006 docs: [종합정비] 구조 재편 — Phase 0+2+4 통합
- Phase 0: INDEX.md 전면 재작성, CLAUDE.md→INDEX.md 통합 삭제
- Phase 0: front/→guides/ 이관(5개 파일), changes/ D7 포맷 통일(3개)
- Phase 0: guides/ai-config-설정.md→ai-config-settings.md D3 통일
- Phase 2: architecture/+specs/→system/ 이관(6개 이동, 4개 폐기)
- Phase 2: 13개 파일 경로 참조 수정 (specs/→system/, architecture/→system/)
- Phase 4: 7개 파일 11개 교차참조 깨진 링크 수정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:03:04 +09:00

9.5 KiB

SAM 서버 동작 원리 초보자 가이드

작성일: 2026-02-22 대상: SAM 프로젝트에 새로 합류한 개발자

서버 인프라 학습 시리즈 | Part 1 of 3 1. 서버 동작 원리2. Nginx & FastCGI3. PHP-FPM


1. 개요

1.1 이 문서의 목적

SAM 시스템에서 웹 요청이 어떤 경로로 흐르는지, git push 후 서버에서 무슨 일이 일어나는지를 설명한다. 설정값 나열이 아닌, **"왜 이런 구조인가"**에 초점을 맞춘다.

1.2 SAM 전체 구조

브라우저 → Nginx (SSL 종료, 도메인별 라우팅)
              │
     ┌────┬───┴───┬─────┬─────┐
     ▼    ▼       ▼     ▼     ▼
    MNG  API   React  Sales  5130     ← 5개 서비스
   (PHP)(PHP) (Node) (PHP) (PHP7.3)
     └────┴───┬───┴─────┴─────┘
              ▼
           MySQL 8.0                  ← 단일 DB 공유

2. 웹 요청의 여정: URL에서 화면까지

2.1 전체 흐름

https://mng.sam.kr/orders 접속 시:

브라우저 →① Nginx →② PHP-FPM →③ Laravel →④ MySQL
                                              │
브라우저 ←────────────────────────────── ⑤ 응답

2.2 Step 1: 브라우저 → Nginx

Nginx는 도메인 이름을 보고 어떤 서비스로 보낼지 결정한다.

  • mng.sam.kr → MNG 컨테이너의 PHP-FPM (포트 9000)
  • api.sam.kr → API 컨테이너의 PHP-FPM (포트 9000)
  • dev.sam.kr → React 컨테이너의 Node.js (포트 3000)

또한 HTTP(80) 요청을 HTTPS(443)로 리다이렉트하고, SSL 인증서를 처리한다. 이를 SSL 종료(SSL Termination)라 한다. 내부 통신은 암호화 없이 빠르게 진행된다.

2.3 Step 2: Nginx → PHP-FPM

Nginx는 PHP 코드를 직접 실행하지 못한다. 대신 FastCGI 프로토콜로 PHP-FPM에 요청을 전달한다.

Nginx: "이 PHP 파일을 실행해줘" → fastcgi_pass mng:9000
PHP-FPM: "결과 HTML이야" → Nginx → 브라우저

PHP-FPM은 여러 워커 프로세스를 미리 만들어 두고, 요청이 오면 빈 워커에 할당한다. MNG의 경우 최대 20개 워커(pm.max_children = 20)가 동시에 요청을 처리할 수 있다.

2.4 Step 3: PHP-FPM → Laravel

PHP-FPM이 실행하는 진입점은 public/index.php다. 여기서 Laravel 프레임워크가 시작된다.

public/index.php
  → Bootstrap (설정 로드, 서비스 등록)
  → 미들웨어 (인증, 권한, 로깅)
  → 라우터 (URL → 컨트롤러 매핑)
  → 컨트롤러 (비즈니스 로직)
  → 뷰 렌더링 (Blade 템플릿 → HTML)

2.5 Step 4: Laravel → MySQL

컨트롤러에서 Eloquent ORM으로 DB를 조회한다. 예를 들어:

// 코드: Order::where('status', 'active')->get();
// 실제 SQL: SELECT * FROM orders WHERE status = 'active' AND tenant_id = 1;

tenant_id는 글로벌 스코프로 자동 추가되어, 다른 테넌트의 데이터가 섞이지 않는다.

2.6 Step 5: 응답이 돌아오는 길

MySQL → Laravel(HTML 생성) → PHP-FPM → Nginx → 브라우저 순으로 돌아온다. MNG는 HTMX를 사용하므로, 이후 상호작용은 HTML 조각(partial)만 주고받아 페이지 전체를 새로고침하지 않는다.


3. 각 구성 요소의 역할

구성 요소 역할 비유
Nginx 리버스 프록시, SSL, 정적 파일 안내 데스크
PHP-FPM PHP 워커 풀 관리 창구 직원 팀
Laravel MVC, 라우팅, 비즈니스 로직 업무 매뉴얼
MySQL 데이터 저장/조회 서류 보관실
Supervisor 프로세스 감시, 자동 재시작 관리 감독관

3.1 Supervisor가 관리하는 프로세스

각 컨테이너 안에서 Supervisor가 여러 프로세스를 관리한다.

API 컨테이너 (sam-api-1):

  • php-fpm — PHP 요청 처리
  • nginx — 컨테이너 내부 웹서버
  • queue-worker — 백그라운드 작업 (이메일, 알림 등)
  • scheduler — 60초마다 예약 작업 실행 (schedule:run)

MNG 컨테이너 (sam-mng-1):

  • php-fpm, nginx — 위와 동일
  • queue-worker x2 — 2개 워커가 병렬 처리

4. 로컬 환경 vs 서버 환경

4.1 비교

[로컬 - Docker]                [서버 - Bare-metal]
┌───────────────┐              ┌───────────────┐
│ sam-nginx-1   │              │ Nginx         │
├───────────────┤              ├───────────────┤
│ sam-mng-1     │              │ MNG (직접)    │
│ sam-api-1     │              │ API (직접)    │
├───────────────┤              ├───────────────┤
│ sam-mysql-1   │              │ MySQL (직접)  │
└───────────────┘              └───────────────┘
 네트워크: samnet               네트워크: localhost

4.2 핵심 차이

항목 로컬 (Docker) 서버 (Bare-metal)
DB 접속 DB_HOST=sam-mysql-1 DB_HOST=127.0.0.1
코드 반영 볼륨 마운트 (실시간) git pull 필요
명령 실행 docker exec sam-api-1 php artisan ... php artisan ...

5. "git push하면 무슨 일이 일어나는가?"

5.1 배포 흐름 다이어그램

개발자 PC (WSL)              Gitea 서버              운영 서버
┌──────────┐    push     ┌──────────┐    pull     ┌──────────┐
│ 코드 수정 │ ──────────→ │  원격     │ ←───────── │ 서버에서  │
│ git add   │            │  저장소   │            │ 수동 pull │
│ git commit│            └──────────┘            └──────────┘
└──────────┘

주의: 자동 배포(CI/CD)가 없다. 서버에서 수동으로 git pull 해야 반영된다.

5.2 PHP 앱 배포 (MNG, API)

# 서버에서 실행하는 명령 (개발팀장이 수행)
cd /home/webservice/api
git pull                    # ① 최신 코드 받기
composer install            # ② 패키지 의존성 동기화
php artisan migrate         # ③ DB 구조 변경 적용
php artisan config:clear    # ④ 설정 캐시 초기화

각 명령이 필요한 이유:

명령 왜 필요한가
git pull 코드를 최신 상태로 동기화
composer install 새로 추가된 PHP 패키지 설치 (composer.json 변경 시)
php artisan migrate 새 테이블/컬럼 생성 등 DB 스키마 적용 (API만)
php artisan config:clear .env 또는 config/ 변경 시 캐시된 설정 갱신

5.3 React 앱 배포 (Next.js)

서버 스펙(2코어, 3.8GB RAM)으로는 Next.js 빌드가 메모리 부족으로 실패한다. 따라서 로컬에서 빌드 → 결과물을 서버에 업로드하는 방식을 사용한다.

# deploy.sh가 수행하는 5단계
① 로컬에서 npm run build     # standalone 빌드
② tar.gz로 압축              # .next/standalone + static + public
③ scp로 서버 업로드           # 압축 파일 전송
④ 서버에서 압축 해제 + 시작   # node server.js (포트 3001)
⑤ 로컬 정리                  # 임시 파일 삭제

6. SAM 도메인별 요청 경로

6.1 도메인 → 서비스 매핑

도메인 서비스 기술 스택 응답 형태
mng.sam.kr MNG Laravel + Blade + HTMX HTML (서버 렌더링)
api.sam.kr API Laravel JSON
dev.sam.kr React Next.js HTML (SSR/CSR)
sales.sam.kr Sales Laravel HTML
5130.sam.kr 5130 PHP 7.3 (레거시) HTML

6.2 서비스별 요청 흐름

MNG (관리자 화면 — Blade + HTMX):

브라우저 → Nginx(:443) → MNG PHP-FPM(:9000) → Laravel → Blade HTML
이후 HTMX가 HTML 조각을 Ajax로 교체 (전체 새로고침 없음)

API (REST API — JSON 응답):

React/외부 → Nginx(:443) → API PHP-FPM(:9000) → Laravel → JSON
인증: Bearer 토큰 (Authorization 헤더)

React (Next.js — SSR + CSR):

브라우저 → Nginx(:443) → Node.js(:3000) → SSR HTML
이후 React 하이드레이션 → CSR (클라이언트 렌더링)
API 호출 시 → Next.js API Route 프록시 → api.sam.kr

관련 문서

학습 시리즈 — 다음 문서:

순서 문서 설명
Part 2 nginx-fastcgi-guide.md Nginx와 FastCGI 프로토콜 심화
Part 3 php-fpm-guide.md PHP-FPM 프로세스 관리 심화

참고 문서:

문서 설명
docker-setup.md Docker 환경 설정값 상세
overview.md 시스템 아키텍처 레퍼런스
production-deployment-plan.md 운영 배포 계획
dev-commands.md 개발 명령어 모음

최종 업데이트: 2026-02-22