축하합니다! https://까지 적용된 Nginx + 워드프레스(LEMP) 서버를 완성하셨습니다. 이제 당신의 웹사이트는 안전하게 작동하지만… 느릴 수 있습니다.
방문자가 1명일 땐 괜찮지만, 100명이 동시에 접속하면 어떻게 될까요? Nginx는 100개의 요청을 모두 PHP-FPM으로 넘기고, PHP는 100번 워드프레스를 실행하며, MariaDB는 100번의 데이터베이스 쿼리를 처리해야 합니다. 서버는 순식간에 과부하에 걸릴 것입니다.
이 문제를 해결하는 가장 강력한 무기가 바로 Nginx 캐시입니다.
- 비유: 지금 당신의 Nginx는 ‘성실한 비서’입니다. 방문자가 올 때마다 ‘사장님(워드프레스/PHP)’에게 물어보고 답을 받아옵니다.
- 캐시 적용: Nginx를 ‘똑똑한 비서’로 만듭니다. 첫 방문자의 질문과 사장님의 답변을 ‘사진’으로 찍어(캐시) 보관합니다. 다음 방문자가 같은 질문을 하면, 사장님을 깨울 필요 없이 1초 만에 ‘사진(캐시)’을 복사해 나눠줍니다.
이 ‘사진(캐시)’은 워드프레스(PHP)를 아예 실행시키지 않기 때문에, 응답 속도가 10배~100배 빨라질 수 있습니다. 2025년 기준, Nginx의 fastcgi_cache를 설정하는 핵심 3단계를 알려드립니다.
(참고: 우리는 Nginx가 직접 PHP를 처리(LEMP)하므로, proxy_cache가 아닌 fastcgi_cache를 사용합니다. 개념은 100% 동일합니다.)
1. 핵심 1: fastcgi_cache_path (캐시 ‘창고’ 만들기)
가장 먼저 Nginx가 ‘사진(캐시)’을 보관할 ‘창고’를 서버에 만들어야 합니다. 이 설정은 서버 전체에 적용되므로, 메인 설정 파일인 nginx.conf의 http 블록 안에 추가합니다.
- 메인 Nginx 설정 파일을 엽니다.
Bash
sudo nano /etc/nginx/nginx.conf http { ... }블록 안, (주로gzip설정 근처)에 다음 한 줄을 추가합니다.Nginxhttp { # ... (기존 설정들) ... ## --- FastCGI Cache 설정 --- fastcgi_cache_path /var/cache/nginx-fastcgi levels=1:2 keys_zone=wp_cache:10m max_size=1g inactive=60m use_temp_path=off; ## --------------------------- # ... (기존 설정들) ... }
- 설정 분석:
fastcgi_cache_path /var/cache/nginx-fastcgi: 캐시를 저장할 실제 ‘폴더’ 위치입니다.levels=1:2: 캐시 파일을 효율적으로 관리하기 위한 하위 디렉터리 구조입니다. (그대로 사용)keys_zone=wp_cache:10m: 이 ‘창고’의 ‘관리 대장(Index)’입니다.wp_cache라는 이름의 창고에 10MB의 메모리를 할당해 캐시 목록을 관리합니다. (10MB면 수만 개의 페이지를 기록하기에 충분합니다.)max_size=1g: 창고의 ‘최대 크기’입니다. 여기서는 1GB로 설정했습니다.inactive=60m: ‘재고 정리’ 규칙입니다. 60분 동안 아무도 찾지 않은 ‘사진(캐시)’은 유효 기간이 남아있어도 창고에서 치웁니다.
2. 핵심 2: fastcgi_cache_bypass (캐시 ‘무시’ 규칙, “VIP 리스트”)
이것이 캐시 설정의 핵심입니다. 모든 것을 캐시하면 큰일 납니다.
만약 /wp-admin 관리자 페이지가 캐시된다면? 모든 방문자가 당신의 관리자 페이지를 보게 됩니다. 만약 로그인한 사용자의 페이지가 캐시된다면? 모든 방문자가 “아무개님, 환영합니다!”라는 메시지를 보게 됩니다.
따라서 Nginx에게 **”이 손님은 VIP(로그인 유저)니까, 캐시(사진)를 주지 말고 무조건 사장님(PHP)께 모셔라!”**라고 알려줘야 합니다.
- 워드프레스 사이트 설정 파일을 엽니다.
Bash
sudo nano /etc/nginx/sites-available/wordpress server { ... }블록 안, (주로index줄 아래)에 다음 ‘무시(bypass)’ 로직을 추가합니다.Nginxserver { listen 443 ssl ...; server_name my-site.com www.my-site.com; root /var/www/html/wordpress; index index.php; # --- 캐시 무시(Bypass) 로직 --- # 1. 기본값: 캐시 무시 안함 (0) set $skip_cache 0; # 2. POST 요청 (댓글, 로그인, 양식 제출)은 절대 캐시 안함 if ($request_method = POST) { set $skip_cache 1; } # 3. URL에 ?가 붙는 쿼리 스트링은 캐시 안함 (효율을 위함) # (선택 사항: ?page=2 등도 캐시하려면 이 줄을 주석 처리) if ($query_string != "") { set $skip_cache 1; } # 4. 관리자 페이지, 로그인, API 등 핵심 경로는 캐시 안함 if ($request_uri ~* "/(wp-admin|wp-login.php|xmlrpc.php|wp-json)") { set $skip_cache 1; } # 5. 로그인한 사용자(쿠키 확인)는 캐시 안함 (가장 중요!) if ($http_cookie ~* "wordpress_logged_in_") { set $skip_cache 1; } # --- 로직 끝 --- # ... (location / { ... } ) ... # ... (location ~ \.php$ { ... } ) ... }
3. 핵심 3: fastcgi_cache (캐시 ‘적용’ 및 ‘유효 기간’ 설정)
이제 1번에서 만든 ‘창고’와 2번에서 만든 ‘무시 규칙’을 실제 PHP 처리기(location ~ \.php$)에 적용할 차례입니다.
- 계속해서
wordpress설정 파일(server블록 안)의location ~ \.php$ { ... }블록을 찾아 수정합니다.Nginxlocation ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; # ⬅️ 본인의 PHP-FPM 경로 # --- 1. 캐시 창고 지정 --- fastcgi_cache wp_cache; # 1번에서 만든 keys_zone 이름(wp_cache) 사용 # --- 2. 캐시 무시 규칙 적용 --- fastcgi_cache_bypass $skip_cache; # 2번 변수($skip_cache)가 1이면 캐시 무시 fastcgi_no_cache $skip_cache; # 캐시를 저장하지도 않음 (Bypass와 세트) # --- 3. 캐시 유효 기간 --- # "200(성공)" 응답은 60분간 캐시 fastcgi_cache_valid 200 60m; # "301(영구 이동)" 응답은 1일간 캐시 fastcgi_cache_valid 301 1d; # "404(못 찾음)" 에러는 5분간 캐시 (에러 페이지도 캐시) fastcgi_cache_valid 404 5m; # --- 4. 캐시 '바코드(Key)' 규칙 --- # 캐시 파일을 식별하는 고유 키 (이대로 사용) fastcgi_cache_key "$scheme$request_method$host$request_uri"; # (보너스) 비상 사태 대비: PHP/DB가 죽어도, 마지막 캐시(stale)를 대신 보여줌 fastcgi_cache_use_stale error timeout invalid_header http_500; # (보너스) 캐시 상태 확인용 헤더 (개발 시 유용) add_header X-FastCGI-Cache $fastcgi_cache_status; }
4. 🏁 적용 및 확인: 캐시가 작동하는지 확인하기
모든 설정이 끝났습니다. Nginx를 다시 시작하고 캐시가 잘 작동하는지 확인합니다.
- Nginx 설정 테스트 및 재시작:
Bash
sudo nginx -t # "syntax is ok", "test is successful" 메시지 확인 sudo systemctl restart nginx - 확인 (가장 중요):
- 로그아웃 상태로 당신의 웹사이트(
https://my-site.com)에 접속합니다. - 브라우저의 개발자 도구(F12) -> [Network] 탭을 엽니다.
- 페이지를 **새로고침(F5)**합니다.
my-site.com의Response Headers를 확인합니다.
[첫 번째 접속]
X-FastCGI-Cache: MISS(캐시(사진)가 없어서 ‘사장님(PHP)’에게 직접 물어봄)[두 번째 새로고침]
X-FastCGI-Cache: HIT(캐시(사진)를 찾음! PHP를 실행하지 않고 Nginx가 1초 만에 응답함)[로그인하고 접속]
X-FastCGI-Cache: BYPASS(‘VIP 손님’이므로 ‘무시 규칙’이 작동해 ‘사장님(PHP)’에게 바로 감) - 로그아웃 상태로 당신의 웹사이트(
HIT가 뜨는 것을 확인했다면, 당신의 서버는 이제 방문자가 100명이 아니라 10,000명이 와도 거뜬히 버틸 수 있는 강력한 엔진을 갖추게 되었습니다.