Files
sam-docs/guides/php-fpm-guide.md
김보곤 d2b4264b13 docs: [guides] 서버 인프라 학습 시리즈 연결
- 3개 가이드에 시리즈 배너 추가 (Part 1/2/3)
- 관련 문서 섹션에 시리즈 네비게이션 추가
- INDEX.md에 시리즈 순서 반영
2026-02-26 20:36:00 +09:00

8.7 KiB

PHP-FPM 초보자 가이드

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

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


1. 개요

1.1 PHP-FPM이란

PHP-FPM(FastCGI Process Manager)은 PHP 코드를 실행하는 프로세스 관리자다. Nginx는 PHP를 직접 실행하지 못하므로, PHP-FPM이 대신 실행하고 결과를 돌려준다.

1.2 이 문서의 목적

서버 동작 원리 가이드에서 PHP-FPM을 간략히 소개했다. 이 문서는 왜 필요한지, 어떻게 동작하는지, SAM에서 어떤 설정으로 쓰이는지를 다룬다.


2. PHP가 웹에서 동작하는 방식의 역사

2.1 CGI → mod_php → PHP-FPM

[1세대 CGI]     요청마다 PHP 프로세스 생성/종료 → 느림
[2세대 mod_php] Apache에 PHP 내장 → 빠르지만 Nginx 불가, 메모리 낭비
[3세대 PHP-FPM] Nginx와 분리, 워커 풀 재사용 → 빠르고 유연 ← SAM이 사용

비유로 이해하기:

세대 비유
CGI 손님마다 직원을 채용하고 해고하는 식당
mod_php 직원이 주방장(Apache)과 한 몸 — 따로 관리 불가
PHP-FPM 안내 데스크(Nginx)와 업무 창구(PHP-FPM) 분리된 은행

2.2 요약

세대 방식 장점 단점
CGI 매번 프로세스 생성 단순 느림, 리소스 낭비
mod_php Apache에 내장 CGI보다 빠름 Nginx 불가, 메모리 낭비
PHP-FPM 독립 프로세스 관리 빠름, 유연 설정 필요

3. PHP-FPM의 구조

3.1 Master / Worker 모델

PHP-FPM은 Master 프로세스 1개와 Worker 프로세스 여러 개로 구성된다.

PHP-FPM
┌──────────────────────────────────┐
│  Master 프로세스 (관리자)          │
│  ├── Worker 1 (대기 중)           │
│  ├── Worker 2 (요청 처리 중)      │
│  ├── Worker 3 (대기 중)           │
│  ├── Worker 4 (요청 처리 중)      │
│  └── Worker 5 (대기 중)           │
└──────────────────────────────────┘

은행 창구 비유:

PHP-FPM 은행
Master 프로세스 지점장 (직원 수 조절, 감독)
Worker 프로세스 창구 직원 (실제 업무 처리)
pm.max_children 최대 창구 수
요청 큐 대기 번호표 줄
  • Master: 워커 생성/종료, 비정상 워커 재시작, 포트 9000 대기
  • Worker: PHP 코드 실행, 1 Worker = 1 요청, 완료 후 다음 요청 대기

3.2 포트 9000과 프로세스 관리 모드

PHP-FPM은 TCP 포트 9000에서 요청을 기다린다.

Nginx ──── TCP 9000 ────→ PHP-FPM Master ──→ 빈 Worker에 배정

Master가 Worker 수를 관리하는 3가지 모드:

모드 설명 SAM
static 항상 고정 수 유지 -
dynamic 트래픽에 따라 조절 사용 중
ondemand 요청 올 때만 생성 -

4. Nginx와 PHP-FPM의 관계

4.1 왜 Nginx는 PHP를 직접 못 실행하는가

Nginx는 정적 파일 서빙과 리버스 프록시 전용이다. PHP 해석 엔진이 없으므로 .php 파일을 실행할 수 없다.

4.2 FastCGI 프로토콜

Nginx와 PHP-FPM은 FastCGI 프로토콜로 통신한다.

브라우저 ──HTTP──→ Nginx ──FastCGI──→ PHP-FPM ──→ PHP 실행
                                                    │
브라우저 ←──HTTP── Nginx ←──FastCGI── PHP-FPM ←────┘

Nginx가 FastCGI로 전달하는 주요 정보:

  • SCRIPT_FILENAME — 실행할 PHP 파일 경로 (/var/www/mng/public/index.php)
  • REQUEST_METHOD — GET, POST 등
  • QUERY_STRING — URL 파라미터

4.3 역할 분담

┌─────────────────────┐      ┌─────────────────────┐
│       Nginx          │      │      PHP-FPM         │
│                      │ TCP  │                      │
│ • SSL 종료           │ 9000 │ • PHP 코드 실행      │
│ • 도메인 라우팅      │─────→│ • Laravel 구동       │
│ • 정적 파일 서빙     │      │ • DB 조회            │
│ • 보안 필터링        │      │ • HTML/JSON 생성     │
└─────────────────────┘      └─────────────────────┘

5. SAM에서의 PHP-FPM

5.1 컨테이너 구조

Docker
├── sam-nginx-1 ── 외부 리버스 프록시
├── sam-api-1
│   └── Supervisor
│       ├── php-fpm      ← 포트 9000
│       ├── nginx        ← 컨테이너 내부 웹서버
│       ├── queue-worker ← 백그라운드 작업
│       └── scheduler    ← 60초 예약 작업
├── sam-mng-1
│   └── Supervisor
│       ├── php-fpm      ← 포트 9000
│       ├── nginx        ← 컨테이너 내부 웹서버
│       └── queue-worker x2
└── sam-mysql-1

Supervisor가 PHP-FPM과 Nginx를 함께 관리한다. 컨테이너 시작 시 Supervisor가 모든 프로세스를 기동한다.

5.2 PHP-FPM 설정 (www.conf)

SAM 설정 파일 위치: docker/mng/www.conf

[www]
user = www-data
group = www-data
listen = 0.0.0.0:9000

pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

각 설정의 의미:

설정 의미
pm dynamic 트래픽에 따라 워커 수 조절
pm.max_children 20 최대 동시 처리 수 (= 최대 창구 20개)
pm.start_servers 5 시작 시 워커 수
pm.min_spare_servers 5 최소 대기 워커 수
pm.max_spare_servers 10 최대 대기 워커 수
pm.max_requests 500 500건 처리 후 워커 재시작 (메모리 누수 방지)

5.3 워커 수의 동적 변화

워커 수
20 ┤                         ■■■■ (피크)
10 ┤               ■■■■■          ■■■■■
 5 ┤ ■■■■■■■■■■■■■                     ■■■■■■■■
 0 ┤──────────────────────────────────────────────
     새벽        오전        점심       오후

5.4 Docker 이미지

SAM은 php:8.4-fpm 공식 이미지를 기반으로 한다. 이미지 이름의 fpm이 PHP-FPM 내장을 의미한다.

FROM php:8.4-fpm
# Supervisor로 php-fpm + nginx 동시 기동
CMD ["/usr/bin/supervisord"]

6. 자주 묻는 질문

6.1 "502 Bad Gateway 에러가 뭔가요?"

Nginx가 PHP-FPM에 연결 실패 시 발생한다. PHP-FPM이 죽었거나, 컨테이너가 비정상 시작된 경우다.

# 컨테이너 상태 확인
docker ps

# 로그 확인
docker logs sam-mng-1

6.2 "워커가 부족하면?"

20개 워커가 모두 처리 중이면 새 요청은 대기열에 들어간다. 너무 오래 대기하면 504 Gateway Timeout이 발생한다. pm.max_children을 올리거나 느린 코드를 최적화한다.

6.3 "PHP-FPM을 재시작하려면?"

# 컨테이너 전체 재시작
docker restart sam-mng-1

# PHP-FPM만 재시작
docker exec sam-mng-1 supervisorctl restart php-fpm

6.4 "프로세스 상태를 확인하려면?"

docker exec sam-mng-1 supervisorctl status
# nginx                   RUNNING   pid 8, uptime 2:30:00
# php-fpm                 RUNNING   pid 9, uptime 2:30:00
# queue-worker_00         RUNNING   pid 10, uptime 2:30:00

6.5 "php artisan serve와 뭐가 다른가요?"

php artisan serve는 개발용 간이 서버로 동시 요청 1개만 처리한다. PHP-FPM은 워커 수만큼 동시 처리가 가능한 프로덕션용이다. SAM은 PHP-FPM을 사용한다.


관련 문서

학습 시리즈:

순서 문서 설명
Part 1 server-how-it-works.md 서버 동작 원리 전체 흐름
Part 2 nginx-fastcgi-guide.md Nginx와 FastCGI 프로토콜 심화 (이전)

참고 문서:

문서 설명
docker-setup.md Docker 환경 설정값 상세

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