docs: [guides] Nginx & FastCGI 초보자 가이드 추가
- Nginx 개념 (웹서버, 리버스 프록시, SSL 종료) - FastCGI 프로토콜 (CGI→FastCGI 발전, 바이너리 프로토콜) - nginx.conf 설정 해부 (try_files, fastcgi_pass, SCRIPT_FILENAME) - SAM 2계층 Nginx 구조 및 도메인별 라우팅 - FastCGI vs HTTP 프록시 비교 - PPTX 프레젠테이션 포함
This commit is contained in:
1
INDEX.md
1
INDEX.md
@@ -105,6 +105,7 @@ docs/
|
||||
| [production-env-sync.md](guides/production-env-sync.md) | 운영 전환 시 .env 동기화 절차 | 테스트→운영 전환 시 |
|
||||
| [server-how-it-works.md](guides/server-how-it-works.md) | 서버 동작 원리 초보자 가이드 | 신규 합류 시 |
|
||||
| [php-fpm-guide.md](guides/php-fpm-guide.md) | PHP-FPM 초보자 가이드 | PHP-FPM 개념 이해 시 |
|
||||
| [nginx-fastcgi-guide.md](guides/nginx-fastcgi-guide.md) | Nginx & FastCGI 초보자 가이드 | Nginx/FastCGI 개념 이해 시 |
|
||||
| [jenkins-setup-guide.md](guides/jenkins-setup-guide.md) | Jenkins CI/CD 셋업 가이드 | Jenkins 설치/설정 시 |
|
||||
|
||||
### quickstart/ - 빠른 시작
|
||||
|
||||
260
guides/nginx-fastcgi-guide.md
Normal file
260
guides/nginx-fastcgi-guide.md
Normal file
@@ -0,0 +1,260 @@
|
||||
# Nginx & FastCGI 초보자 가이드
|
||||
|
||||
> **작성일**: 2026-02-22
|
||||
> **대상**: SAM 프로젝트에 새로 합류한 개발자
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 이 문서의 목적
|
||||
|
||||
"Nginx가 뭐지?", "FastCGI가 뭐지?" — 이 두 질문에 답하는 문서다.
|
||||
[서버 동작 원리 가이드](server-how-it-works.md)와 [PHP-FPM 가이드](php-fpm-guide.md)에서 간략히 언급한 내용을 **깊이 파고든다**.
|
||||
|
||||
### 1.2 핵심 한 줄 정리
|
||||
|
||||
- **Nginx** = 요청을 받아서 적절한 곳에 전달하는 **교통 경찰**
|
||||
- **FastCGI** = Nginx와 PHP-FPM이 대화하는 **통신 규약(프로토콜)**
|
||||
|
||||
---
|
||||
|
||||
## 2. Nginx란?
|
||||
|
||||
### 2.1 웹서버가 하는 일
|
||||
|
||||
웹서버는 브라우저의 요청을 받아서 응답을 돌려주는 프로그램이다.
|
||||
|
||||
```
|
||||
브라우저: "index.html 주세요"
|
||||
웹서버: "여기 있습니다" (파일 내용 전송)
|
||||
```
|
||||
|
||||
### 2.2 Nginx의 정체
|
||||
|
||||
Nginx(엔진엑스)는 **고성능 웹서버이자 리버스 프록시**다. 2004년 러시아 개발자 이고르 시소예프가 만들었다.
|
||||
|
||||
**비유**: 대형 호텔의 프런트 데스크
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Nginx (프런트 데스크) │
|
||||
│ │
|
||||
│ 손님(브라우저)이 오면: │
|
||||
│ │
|
||||
│ "이미지 주세요" → 직접 서빙 (정적 파일) │
|
||||
│ "PHP 실행해줘" → PHP-FPM에 전달 (FastCGI) │
|
||||
│ "React 페이지" → Node.js에 전달 (프록시) │
|
||||
│ "API 호출" → API 서버에 전달 (프록시) │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.3 Nginx vs Apache
|
||||
|
||||
| 항목 | Nginx | Apache |
|
||||
|------|-------|--------|
|
||||
| 아키텍처 | **이벤트 기반** (비동기) | 프로세스/스레드 기반 |
|
||||
| 동시 접속 | 수만 개 가능 | 수천 개 수준 |
|
||||
| 메모리 | 적게 사용 | 많이 사용 |
|
||||
| 정적 파일 | **매우 빠름** | 보통 |
|
||||
| PHP 실행 | 직접 불가 (FastCGI 필요) | mod_php로 직접 가능 |
|
||||
| SAM에서 | **사용 중** | 사용 안 함 |
|
||||
|
||||
**왜 SAM은 Nginx를 쓰는가**: 서버 스펙(2코어/3.8GB)이 제한적이므로, 적은 메모리로 5개 서비스를 동시 라우팅할 수 있는 Nginx가 적합하다.
|
||||
|
||||
### 2.4 Nginx의 3가지 역할
|
||||
|
||||
```
|
||||
역할 1 — 정적 파일 서빙: logo.png → Nginx가 직접 전송 (PHP 개입 없음)
|
||||
역할 2 — 리버스 프록시: PHP 요청 → PHP-FPM, React 요청 → Node.js
|
||||
역할 3 — SSL 종료: HTTPS(암호화) → Nginx에서 해독 → 내부는 HTTP(평문)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. FastCGI란?
|
||||
|
||||
### 3.1 먼저 CGI를 이해하자
|
||||
|
||||
**CGI**(Common Gateway Interface)는 웹서버가 외부 프로그램을 실행하는 규약이다. 1993년에 만들어졌다.
|
||||
|
||||
```
|
||||
브라우저 → 웹서버 → "PHP 프로그램을 실행해서 결과를 줘"
|
||||
↓
|
||||
[새 프로세스 생성] → PHP 실행 → 결과 → [프로세스 종료]
|
||||
```
|
||||
|
||||
**문제**: 요청마다 프로세스를 새로 생성하고 종료한다. 100명이 동시에 접속하면 100개 프로세스가 생겼다 사라진다. **느리고 비효율적**이다.
|
||||
|
||||
### 3.2 FastCGI가 해결한 것
|
||||
|
||||
**FastCGI**는 1996년에 CGI의 문제를 해결하기 위해 만들어졌다. 핵심 차이:
|
||||
|
||||
```
|
||||
[CGI] 요청 → 프로세스 생성 → 실행 → 종료 → 요청 → 생성 → 실행 → 종료
|
||||
[FastCGI] 프로세스가 미리 떠 있음 → 요청 → 실행 → 대기 → 요청 → 실행 → 대기
|
||||
```
|
||||
|
||||
**비유**: CGI는 택시(매번 부르고 보냄), FastCGI는 전용 기사(항상 대기 중).
|
||||
|
||||
### 3.3 FastCGI는 프로토콜이다
|
||||
|
||||
FastCGI는 프로그램이 아니라 **통신 규약(프로토콜)**이다. HTTP처럼 "이렇게 데이터를 주고받자"는 약속이다.
|
||||
|
||||
```
|
||||
┌──────────┐ ┌──────────┐
|
||||
│ Nginx │ ── FastCGI 규약 ── │ PHP-FPM │
|
||||
│ (클라이언트) │ │ (서버) │
|
||||
└──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
- HTTP: 브라우저와 웹서버 사이의 규약
|
||||
- **FastCGI**: 웹서버와 애플리케이션 서버 사이의 규약
|
||||
- 둘은 다른 프로토콜이다 (FastCGI는 바이너리, HTTP는 텍스트)
|
||||
|
||||
### 3.4 FastCGI가 전달하는 정보
|
||||
|
||||
Nginx가 PHP-FPM에 보내는 주요 파라미터:
|
||||
|
||||
| 파라미터 | 의미 | 예시 |
|
||||
|---------|------|------|
|
||||
| `SCRIPT_FILENAME` | 실행할 PHP 파일 | `/var/www/mng/public/index.php` |
|
||||
| `REQUEST_METHOD` | HTTP 메서드 | `GET`, `POST` |
|
||||
| `QUERY_STRING` | URL 파라미터 | `page=1&sort=name` |
|
||||
| `HTTP_HOST` | 도메인 | `mng.sam.kr` |
|
||||
|
||||
PHP에서 `$_SERVER['REQUEST_METHOD']`, `$_GET` 등으로 접근하는 값이 바로 이것이다.
|
||||
|
||||
---
|
||||
|
||||
## 4. Nginx + FastCGI 동작 원리
|
||||
|
||||
### 4.1 전체 흐름
|
||||
|
||||
`https://mng.sam.kr/orders?page=2` 접속 시:
|
||||
|
||||
```
|
||||
브라우저 →① HTTPS → Nginx(도메인 라우팅) →② try_files → index.php
|
||||
→③ FastCGI → PHP-FPM(:9000) →④ Laravel → DB → HTML →⑤ 응답 역순
|
||||
```
|
||||
|
||||
### 4.2 Nginx 설정 해부
|
||||
|
||||
SAM의 MNG 설정에서 FastCGI 관련 부분:
|
||||
|
||||
```nginx
|
||||
# docker/nginx/nginx.conf (외부 Nginx — MNG 섹션)
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
# ① ② ③
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
include fastcgi_params; # ④
|
||||
fastcgi_pass mng:9000; # ⑤
|
||||
fastcgi_param SCRIPT_FILENAME /var/www/mng/public$fastcgi_script_name; # ⑥
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info; # ⑦
|
||||
fastcgi_param HTTPS on; # ⑧
|
||||
fastcgi_read_timeout 300s; # ⑨
|
||||
}
|
||||
```
|
||||
|
||||
**핵심 줄 해설**:
|
||||
|
||||
- ①②③ `try_files`: 파일 있으면 직접 서빙, 없으면 `index.php`로 (Laravel 진입점)
|
||||
- ⑤ `fastcgi_pass mng:9000`: **핵심! FastCGI 요청을 mng 컨테이너 9000번 포트로 전달**
|
||||
- ⑥ `SCRIPT_FILENAME`: PHP-FPM이 실행할 파일의 절대 경로
|
||||
- ⑧ `HTTPS on`: PHP에서 HTTPS 요청으로 인식하도록 설정
|
||||
- ⑨ `fastcgi_read_timeout`: PHP 응답 대기 최대 300초
|
||||
|
||||
### 4.3 왜 index.php 하나로 모든 요청을 처리하는가
|
||||
|
||||
Laravel은 **프론트 컨트롤러 패턴**을 사용한다. `/orders`, `/users/123` 등 모든 URL이 `public/index.php`를 통과하고, Laravel 라우터가 적절한 컨트롤러로 분배한다. `try_files` 설정이 이를 가능하게 한다.
|
||||
|
||||
---
|
||||
|
||||
## 5. SAM의 Nginx 구조
|
||||
|
||||
### 5.1 2계층 Nginx
|
||||
|
||||
SAM은 Nginx가 **2단계**로 작동한다:
|
||||
|
||||
```
|
||||
브라우저 → [1계층: 외부 Nginx (sam-nginx-1)] → SSL 종료 + 도메인 라우팅
|
||||
│ │
|
||||
▼ ▼
|
||||
[2계층: sam-mng-1] [2계층: sam-api-1]
|
||||
Nginx(:80) Nginx(:80)
|
||||
↓ FastCGI ↓ FastCGI
|
||||
PHP-FPM(:9000) PHP-FPM(:9000)
|
||||
```
|
||||
|
||||
### 5.2 도메인별 라우팅 정리
|
||||
|
||||
| 도메인 | 1계층(외부 Nginx) 동작 | 프로토콜 |
|
||||
|--------|----------------------|---------|
|
||||
| `mng.sam.kr` | `fastcgi_pass mng:9000` | **FastCGI** |
|
||||
| `api.sam.kr` | `fastcgi_pass api:9000` | **FastCGI** |
|
||||
| `dev.sam.kr` | `proxy_pass react:3000` | HTTP 프록시 |
|
||||
| `sales.sam.kr` | `proxy_pass sales:80` | HTTP 프록시 |
|
||||
| `5130.sam.kr` | `proxy_pass php73:80` | HTTP 프록시 |
|
||||
|
||||
> **핵심**: PHP 서비스는 **FastCGI**로, Node.js/레거시 서비스는 **HTTP 프록시**로 연결한다.
|
||||
|
||||
---
|
||||
|
||||
## 6. 자주 묻는 질문
|
||||
|
||||
### 6.1 "FastCGI와 HTTP 프록시의 차이는?"
|
||||
|
||||
| 항목 | FastCGI | HTTP 프록시 |
|
||||
|------|---------|-----------|
|
||||
| 프로토콜 | 바이너리 (FastCGI) | 텍스트 (HTTP) |
|
||||
| 용도 | PHP-FPM 등 CGI 호환 앱 | Node.js, 일반 웹서버 |
|
||||
| Nginx 설정 | `fastcgi_pass` | `proxy_pass` |
|
||||
| SAM에서 | MNG, API | React, Sales, 5130 |
|
||||
|
||||
### 6.2 "try_files가 뭔가요?"
|
||||
|
||||
Nginx가 파일을 찾는 순서를 지정한다:
|
||||
|
||||
```nginx
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
```
|
||||
|
||||
1. `$uri` — `/orders.html` 파일이 있는가? → 없다
|
||||
2. `$uri/` — `/orders/` 디렉토리가 있는가? → 없다
|
||||
3. `/index.php?$query_string` — index.php로 넘긴다 (Laravel이 처리)
|
||||
|
||||
### 6.3 "SCRIPT_FILENAME은 왜 설정하나?"
|
||||
|
||||
PHP-FPM은 어떤 PHP 파일을 실행할지 알아야 한다. Nginx가 FastCGI 파라미터로 알려준다.
|
||||
|
||||
```nginx
|
||||
fastcgi_param SCRIPT_FILENAME /var/www/mng/public$fastcgi_script_name;
|
||||
# /orders 요청 시 → /var/www/mng/public/index.php
|
||||
```
|
||||
|
||||
이 설정이 잘못되면 "File not found" 에러가 발생한다.
|
||||
|
||||
### 6.4 "502/504 에러가 나면?"
|
||||
|
||||
| 에러 | 원인 | 대응 |
|
||||
|------|------|------|
|
||||
| **502 Bad Gateway** | PHP-FPM이 죽었거나 연결 불가 | `docker ps`, `docker logs` 확인 |
|
||||
| **504 Gateway Timeout** | PHP 처리가 너무 오래 걸림 | `fastcgi_read_timeout` 증가 또는 코드 최적화 |
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
| 문서 | 설명 |
|
||||
|------|------|
|
||||
| [server-how-it-works.md](server-how-it-works.md) | 서버 동작 원리 전체 가이드 |
|
||||
| [php-fpm-guide.md](php-fpm-guide.md) | PHP-FPM 초보자 가이드 |
|
||||
| [docker-setup.md](../specs/docker-setup.md) | Docker 환경 설정값 상세 |
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-02-22
|
||||
BIN
guides/nginx-fastcgi-guide.pptx
Normal file
BIN
guides/nginx-fastcgi-guide.pptx
Normal file
Binary file not shown.
Reference in New Issue
Block a user