Files
sam-docs/guides/nginx-fastcgi-guide.md
김보곤 bb28e68847 docs: [guides] Nginx & FastCGI 초보자 가이드 추가
- Nginx 개념 (웹서버, 리버스 프록시, SSL 종료)
- FastCGI 프로토콜 (CGI→FastCGI 발전, 바이너리 프로토콜)
- nginx.conf 설정 해부 (try_files, fastcgi_pass, SCRIPT_FILENAME)
- SAM 2계층 Nginx 구조 및 도메인별 라우팅
- FastCGI vs HTTP 프록시 비교
- PPTX 프레젠테이션 포함
2026-02-26 20:36:00 +09:00

9.4 KiB

Nginx & FastCGI 초보자 가이드

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


1. 개요

1.1 이 문서의 목적

"Nginx가 뭐지?", "FastCGI가 뭐지?" — 이 두 질문에 답하는 문서다. 서버 동작 원리 가이드PHP-FPM 가이드에서 간략히 언급한 내용을 깊이 파고든다.

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 관련 부분:

# 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가 파일을 찾는 순서를 지정한다:

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 파라미터로 알려준다.

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 서버 동작 원리 전체 가이드
php-fpm-guide.md PHP-FPM 초보자 가이드
docker-setup.md Docker 환경 설정값 상세

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