diff --git a/resources/views/academy/nginx-encyclopedia.blade.php b/resources/views/academy/nginx-encyclopedia.blade.php new file mode 100644 index 00000000..369df843 --- /dev/null +++ b/resources/views/academy/nginx-encyclopedia.blade.php @@ -0,0 +1,1229 @@ +@extends('layouts.app') + +@section('title', 'Nginx 백과사전') + +@push('styles') + +@endpush + +@section('content') +
+ + +
+
+
+
+ 아카데미 + + Nginx +
+

Nginx 백과사전

+

기초부터 실전까지 — SAM 프로젝트의 Nginx 설정을 완전 해부하는 교육 가이드

+
+
+
+ Nginx 백과사전 히어로 +
+
+
+
+ +
+ + + + +
+ + + + + {{-- ============================================================ --}} + {{-- 1. 웹 서버란 무엇인가 --}} + {{-- ============================================================ --}} +
+
+

+ 1 + 웹 서버란 무엇인가 +

+ + +
+

+ + 웹 서버의 3가지 역할 +

+
+

비유: 24시간 접수 창구

+

+ 웹 서버는 24시간 열려 있는 접수 창구다. 손님(클라이언트)이 "이 서류 주세요"라고 요청하면, + 접수 담당자(웹 서버)가 서류 창고에서 꺼내주거나, 다른 부서(PHP-FPM)에 처리를 맡기거나, 수상한 손님을 돌려보낸다. +

+
+ +
+ 웹 서버 = 접수 창구 비유 +
+

웹 서버의 3가지 역할: 정적 파일 서빙, 동적 요청 전달, 보안 검사

+ +
+
+

정적 파일 서빙

+

HTML, CSS, JS, 이미지 등
서류 창고에서 바로 꺼내줌

+
+
+

동적 요청 전달

+

PHP-FPM에 처리 위임
"다른 부서에 맡기겠습니다"

+
+
+

보안 검사

+

수상한 요청 차단
"출입 금지 명단" 확인

+
+
+
+ + +
+

+ + Apache vs Nginx 비교 +

+ +
+ Apache vs Nginx 비교 +
+

프로세스 기반(Apache) vs 이벤트 기반(Nginx)

+ +
+
+ + + + + + + + + + + + + + + +
항목ApacheNginx
처리 방식프로세스/스레드 기반이벤트 기반 (비동기)
동시 접속접속마다 프로세스 생성하나의 워커가 수천 개 처리
메모리 사용높음 (접속 비례 증가)낮음 (거의 일정)
정적 파일보통매우 빠름
리버스 프록시가능 (추가 모듈)기본 내장, 뛰어남
+
+
+

SAM이 Nginx를 선택한 이유

+

+ SAM은 5개 도메인(React, API, MNG, Sales, 5130)을 하나의 서버에서 운영한다. + Nginx의 리버스 프록시낮은 메모리 사용량이 이 구조에 최적이다. + 2코어 3.8GB RAM 서버에서도 안정적으로 동작한다. +

+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 2. Nginx란 무엇인가 --}} + {{-- ============================================================ --}} +
+
+

+ 2 + Nginx란 무엇인가 +

+ + +
+

+ + 탄생 배경: C10K 문제 +

+
+
+

+ Nginx(엔진엑스)는 2004년 러시아 개발자 Igor Sysoev가 만들었다. + 당시 웹 서버들은 C10K 문제(동시 1만 개 연결 처리)를 해결하지 못했다. + Apache는 접속마다 프로세스를 생성하여 메모리가 폭발했고, Nginx는 이벤트 기반 아키텍처로 이 문제를 해결했다. +

+
+
+

비유: 식당 주문 방식의 차이

+

+ Apache: 손님마다 전담 웨이터를 배정. 100명이 오면 웨이터 100명 필요.
+ Nginx: 웨이터 1명이 번호표를 나눠주고, 주문이 준비되면 호출. 수천 명도 처리 가능. +

+
+
+
+

2004

+

최초 공개

+
+
+

34%

+

글로벌 시장 점유율

+
+
+

C10K

+

해결한 핵심 문제

+
+
+

이벤트

+

비동기 처리 방식

+
+
+
+
+ + +
+

+ + 설정 파일 계층 구조 +

+ +
+
+ Nginx 설정 계층 구조 +

마트료시카처럼 중첩되는 설정 블록

+
+
+
+

비유: 건물 → 층 → 방

+

+ Nginx 설정은 마트료시카 인형처럼 중첩된다. + 건물 전체 규칙(main) 안에 층별 규칙(http), 층 안에 방별 규칙(server), 방 안에 공간별 규칙(location)이 있다. +

+
+
+# main 컨텍스트 (건물 전체) +worker_processes auto; + +events { # 연결 관리 (관리사무소) + worker_connections 1024; +} + +http { # HTTP 설정 (건물 1층~) + server { # 도메인별 설정 (각 방) + listen 443 ssl; + server_name mng.sam.kr; + + location / { # 경로별 설정 (방 안 공간) + try_files $uri /index.php; + } + } +}
+
+

계층 정리

+

mainevents / httpserverlocation

+

상위 설정은 하위로 상속된다. 하위에서 같은 설정을 하면 덮어쓴다.

+
+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 3. 리버스 프록시 이해하기 --}} + {{-- ============================================================ --}} +
+
+

+ 3 + 리버스 프록시 이해하기 +

+ + +
+

+ + Forward Proxy vs Reverse Proxy +

+
+

비유: 안내 데스크

+

+ Forward Proxy: 회사 직원이 외부 인터넷에 접속할 때 거치는 "사내 인터넷 관문". "나 대신 밖에 나가서 가져와줘."
+ Reverse Proxy: 외부 손님이 회사 내부 서비스에 접근할 때 거치는 "안내 데스크". "손님을 적절한 담당자에게 연결해드리겠습니다." +

+
+ +
+ Forward vs Reverse Proxy 비교 +
+

Forward Proxy는 클라이언트 대리, Reverse Proxy는 서버 대리

+ +
+ + + + + + + + + + + + + + +
항목Forward ProxyReverse Proxy
위치클라이언트 쪽서버 쪽
목적클라이언트 익명성서버 보호/로드 밸런싱
예시회사 프록시, VPNNginx, Cloudflare
SAM 사용사용 안 함외부 Nginx가 이 역할
+
+
+ + +
+

+ + SAM 5개 도메인 라우팅 +

+ +
+ SAM 5개 도메인 라우팅 맵 +
+

외부 Nginx가 도메인별로 각 서비스로 분배하는 구조

+ +
+

+ SAM의 외부 Nginx는 *.sam.kr 와일드카드 SSL 인증서를 사용하여 5개 도메인을 하나의 서버에서 처리한다. + 각 도메인은 server_name 디렉티브로 구분되어 서로 다른 내부 서비스로 전달된다. +

+
+ + + + + + + + + + + + + + + + +
도메인서비스전달 방식설명
dev.sam.krReact (Next.js)proxy_pass http://react:3000프론트엔드 SPA
api.sam.krAPI (Laravel)fastcgi_pass api:9000REST API 서버
mng.sam.krMNG (Laravel)fastcgi_pass mng:9000관리자 웹
sales.sam.krSales (PHP)proxy_pass http://sales:80영업 시스템
5130.sam.kr레거시 (PHP 7.3)proxy_pass http://php73:80기존 5130 시스템
+
+
+
+ + +
+

+ + 프록시 헤더 해설 +

+
+

+ 리버스 프록시는 클라이언트의 원래 정보를 백엔드 서버에 전달해야 한다. 그렇지 않으면 백엔드는 모든 요청이 "Nginx에서 온 것"으로만 보인다. +

+
+proxy_set_header Host $host; # 원래 도메인명 전달 +proxy_set_header X-Real-IP $remote_addr; # 클라이언트 실제 IP +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 거쳐온 IP 목록 +proxy_set_header X-Forwarded-Proto $scheme; # HTTP or HTTPS
+
+

비유: 택배 송장

+

+ 안내 데스크(Nginx)가 택배를 내부 담당자에게 전달할 때, "원래 보낸 사람 이름과 주소"를 송장에 적어 붙여야 한다. + 그래야 담당자가 "이 택배가 어디서 왔는지" 알 수 있다. + Host는 수신자, X-Real-IP는 발송자 주소에 해당한다. +

+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 4. SAM Nginx 설정 완전 해부 --}} + {{-- ============================================================ --}} +
+
+

+ 4 + SAM Nginx 설정 완전 해부 +

+ + +
+

+ + 2계층 Nginx 아키텍처 +

+
+

비유: 건물 정문 경비실 + 각 층 접수 창구

+

+ SAM은 Nginx를 2단계로 사용한다. + 1단계(외부 Nginx)는 건물 정문 경비실로, 어떤 손님이 어느 층으로 가야 하는지 안내한다. + 2단계(내부 Nginx)는 각 층의 접수 창구로, 해당 층의 PHP-FPM에게 실제 업무를 맡긴다. +

+
+ +
+ 2계층 Nginx 아키텍처 +
+

외부 Nginx(도메인 라우팅 + SSL) → 내부 Nginx(PHP-FPM 통신)

+ +
+

── SAM 요청 흐름 ──

+

사용자외부 Nginx (SSL 종료, 도메인 라우팅)

+

├→ react:3000 (proxy_pass) → Next.js

+

├→ api:9000 (fastcgi_pass) → PHP-FPM

+

├→ mng:80내부 Nginx → mng:9000 (fastcgi_pass)

+

├→ sales:80내부 Nginx → sales:9000 (fastcgi_pass)

+

└→ php73:80내부 Nginx → 5130:9000 (fastcgi_pass)

+
+
+ + +
+

+ + 외부 Nginx 설정 분석 +

+
+

+ docker/nginx/nginx.conf — 외부 Nginx는 SSL 인증서를 관리하고 5개 도메인을 각 서비스로 라우팅한다. +

+ +

글로벌 설정

+
+client_max_body_size 100M; # 최대 업로드 크기 100MB + +# SSL 공통 설정 (*.sam.kr 와일드카드 인증서) +ssl_certificate /etc/nginx/ssl/sam.kr.crt; +ssl_certificate_key /etc/nginx/ssl/sam.kr.key; +ssl_protocols TLSv1.2 TLSv1.3;
+ +

React 도메인 (dev.sam.kr) — WebSocket 지원

+
+server { + listen 443 ssl; + server_name dev.sam.kr; + + location / { + proxy_pass http://react:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; # WebSocket (HMR용) + proxy_set_header Connection "upgrade"; + proxy_read_timeout 86400; # 24시간 (개발 HMR) + } +}
+ +

MNG 도메인 (mng.sam.kr) — 정적 캐싱 + FastCGI

+
+server { + listen 443 ssl; + server_name mng.sam.kr; + + # 테넌트 스토리지 이중 프록시 + location ^~ /tenant-storage/ { + proxy_pass http://mng:80/tenant-storage/; + expires 7d; + add_header Cache-Control "public, immutable"; + } + + # 정적 자산 30일 캐싱 + location ~* \.(js|css|png|jpg|svg|ico|woff2?)$ { + expires 30d; + add_header Cache-Control "public"; + access_log off; + } + + # PHP 처리 + location ~ \.php$ { + fastcgi_pass mng:9000; + fastcgi_read_timeout 300; # 5분 (장시간 작업) + } +}
+ +
+

핵심 디렉티브 해설

+
+

try_files $uri $uri/ /index.php?$query_string — 파일이 있으면 서빙, 없으면 Laravel 라우터로 전달

+

fastcgi_pass mng:9000 — PHP-FPM 프로세스에 요청 전달 (FastCGI 프로토콜)

+

proxy_pass http://react:3000 — HTTP 프록시로 요청 전달 (일반 HTTP)

+

^~ /tenant-storage/ — 정규식보다 우선 매칭 (prefix match)

+
+
+
+
+ + +
+

+ + 내부 Nginx 설정 분석 +

+
+

+ 각 컨테이너 내부의 Nginx는 단순하다. listen 80으로 외부 Nginx의 요청을 받고, + fastcgi_pass 127.0.0.1:9000으로 같은 컨테이너의 PHP-FPM에 전달한다. +

+ +

MNG 내부 Nginx (특수: 테넌트 스토리지)

+
+disable_symlinks off; # 심볼릭 링크 허용 (Laravel storage:link) + +# 테넌트 파일 직접 서빙 (alias 사용) +location /tenant-storage/ { + alias /var/www/shared-storage/tenants/; + expires 7d; + add_header Cache-Control "public, immutable"; +} + +location ~ \.php$ { + fastcgi_pass 127.0.0.1:9000; + fastcgi_read_timeout 300; +}
+ +

Sales / 5130 내부 Nginx (공통 패턴)

+
+server { + listen 80; + root /var/www/sales; + client_max_body_size 100M; + + location ~ /\. { + deny all; # 숨김 파일(.env, .git) 접근 차단 + } +}
+ +
+

왜 2계층인가?

+

+ Docker 컨테이너는 격리된 환경이다. 외부 Nginx가 직접 컨테이너 안의 PHP-FPM에 접근하려면 + 복잡한 네트워크 설정이 필요하다. 내부 Nginx를 두면 각 컨테이너가 자체적으로 요청을 처리할 수 있어 관리가 쉽다. + MNG의 테넌트 스토리지 alias처럼 컨테이너 고유의 설정도 독립적으로 관리할 수 있다. +

+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 5. 보안 설정 --}} + {{-- ============================================================ --}} +
+
+

+ 5 + 보안 설정 +

+ + +
+

+ + SSL/TLS 암호화 +

+ +
+
+ SSL/TLS 봉투 자물쇠 비유 +

편지를 봉투에 넣고 자물쇠로 잠그는 것 = SSL

+
+
+
+

비유: 편지 봉투와 자물쇠

+

+ HTTP는 엽서처럼 내용이 공개된 채 전달된다. 누구나 중간에 읽을 수 있다.
+ HTTPS는 편지를 봉투에 넣고 자물쇠(SSL)로 잠근 것이다. 열쇠를 가진 수신자만 열 수 있다. +

+
+
+# SAM SSL 설정 (외부 Nginx) +ssl_certificate /etc/nginx/ssl/sam.kr.crt; # 와일드카드 인증서 +ssl_certificate_key /etc/nginx/ssl/sam.kr.key; # 개인키 +ssl_protocols TLSv1.2 TLSv1.3; # 최신 프로토콜만 +ssl_ciphers HIGH:!aNULL:!MD5; # 강력한 암호화만
+
+

SAM의 SSL 구조

+

+ *.sam.kr 와일드카드 인증서 하나로 모든 서브도메인을 커버한다. + SSL 종료(termination)는 외부 Nginx에서만 이루어지고, 내부 통신은 평문 HTTP를 사용한다. + Docker 내부 네트워크는 격리되어 있으므로 안전하다. +

+
+
+
+
+ + +
+

+ + 보안 필터링 +

+ +
+
+ 보안 필터 입장 불가 명단 +

수상한 요청은 경비원이 차단

+
+
+

경로 트래버설 & 민감 파일 차단 (API 서버)

+
+# 악의적 경로 접근 차단 +if ($request_uri ~* "(\.\.\/|\.\.\\|etc\/passwd|\.env|\.git|\.htaccess|\.sql|@fs\/)") { + return 403; +}
+ +
+
+

../ 경로 트래버설

+

상위 디렉토리 접근 시도

+
+
+

.env 환경 파일

+

DB 비밀번호 등 노출 위험

+
+
+

.git 소스 코드

+

전체 코드 히스토리 노출

+
+
+

etc/passwd 시스템

+

서버 사용자 정보 노출

+
+
+ +

해킹 도구 User-Agent 차단

+
+# 자동 스캔 도구 차단 +if ($http_user_agent ~* "(sqlmap|nikto|nmap|masscan|metasploit|nessus)") { + return 403; +}
+ +

숨김 파일 차단 (Sales/5130 내부 Nginx)

+
+location ~ /\. { + deny all; # .env, .git, .htaccess 등 모두 차단 +}
+
+
+
+ + +
+

+ + 보안 헤더 +

+
+

+ SAM의 Sales 서버에는 다음 보안 헤더가 적용되어 있다. 브라우저에게 "이렇게 동작하라"고 지시하는 보안 규칙이다. +

+
+add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; +add_header X-Frame-Options SAMEORIGIN; +add_header X-Content-Type-Options nosniff; +add_header X-XSS-Protection "1; mode=block";
+
+ + + + + + + + + + + + + + +
헤더역할비유
HSTS항상 HTTPS 강제"이 건물은 정문으로만 출입"
X-Frame-Optionsiframe 삽입 방지"내 간판을 남의 가게에 걸지 마"
X-Content-TypeMIME 타입 고정"라벨 대로만 내용물 취급"
X-XSS-ProtectionXSS 공격 차단"수상한 스크립트 자동 격리"
+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 6. 성능 최적화 --}} + {{-- ============================================================ --}} +
+
+

+ 6 + 성능 최적화 +

+ + +
+

+ + 정적 자산 캐싱 +

+ +
+
+ 정적 자산 캐싱 비유 +

캐시는 자주 쓰는 서류를 책상 위에 두는 것

+
+
+
+

비유: 냉장고에 자주 먹는 반찬 보관

+

+ 매번 마트에 가서 반찬을 사오면 시간이 오래 걸린다(서버에서 매번 전송). + 자주 먹는 반찬은 냉장고(브라우저 캐시)에 넣어두면 바로 꺼내먹을 수 있다. + expires 30d는 "이 반찬은 30일간 신선하다"는 유통기한 표시다. +

+
+
+# 정적 자산 30일 캐싱 (API, MNG 공통) +location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot|map)$ { + expires 30d; + add_header Cache-Control "public"; + access_log off; # 정적 파일은 로그 불필요 +} + +# 테넌트 스토리지 7일 캐싱 (MNG) +location ^~ /tenant-storage/ { + expires 7d; + add_header Cache-Control "public, immutable"; # 변경 안 됨 보장 +}
+
+

immutable이란?

+

+ immutable은 "이 파일은 절대 변하지 않는다"는 선언이다. + 브라우저가 "혹시 바뀌었나요?"라는 재검증 요청조차 보내지 않아 더 빠르다. + 테넌트 파일(로고, 첨부파일)은 업로드 후 변경되지 않으므로 적합하다. +

+
+
+
+
+ + +
+

+ + 타임아웃 설정 +

+
+

+ 서비스마다 처리 시간이 다르므로 타임아웃도 다르게 설정한다. 타임아웃이 너무 짧으면 정상 요청도 끊기고, 너무 길면 오류 상황에서 자원이 낭비된다. +

+
+ + + + + + + + + + + + + + + +
서비스설정이유
Reactproxy_read_timeout86400s (24시간)HMR WebSocket 연결 유지
MNGfastcgi_read_timeout300s (5분)대량 데이터 처리, 엑셀 내보내기
Salesproxy_read_timeout60s (1분)일반 웹 페이지 응답
5130-기본값레거시 (별도 설정 없음)
+
+
+

WebSocket과 HTTP/2

+

+ WebSocket: React(HMR)과 Sales에서 사용. Upgrade: websocket 헤더로 HTTP 연결을 WebSocket으로 전환한다.
+ HTTP/2: Sales와 5130에서 활성화 (http2 on). 하나의 TCP 연결에 여러 요청을 동시에 전송하는 "한 통화에 여러 주문" 방식이다. +

+
+
+
+
+
+ + {{-- ============================================================ --}} + {{-- 7. 트러블슈팅 & 명령어 사전 --}} + {{-- ============================================================ --}} +
+
+

+ 7 + 트러블슈팅 & 명령어 사전 +

+ + +
+

+ + 4대 Nginx 에러 +

+ +
+ 502/504/403/413 에러 카드 +
+

Nginx에서 가장 흔한 4가지 에러와 원인

+ +
+
+

502 Bad Gateway

+

PHP-FPM이 응답하지 않음

+
+

원인

+
    +
  • PHP-FPM 프로세스가 죽었거나 미시작
  • +
  • fastcgi_pass 주소/포트 불일치
  • +
  • PHP 코드에서 메모리 초과
  • +
+

해결

+

docker restart sam-api-1

+
+
+
+

504 Gateway Timeout

+

처리 시간 초과

+
+

원인

+
    +
  • PHP 스크립트가 너무 오래 실행
  • +
  • DB 쿼리 무한 대기
  • +
  • 타임아웃 설정이 너무 짧음
  • +
+

해결

+

fastcgi_read_timeout 값 확인

+
+
+
+

403 Forbidden

+

접근 권한 없음

+
+

원인

+
    +
  • 파일/디렉토리 권한 부족
  • +
  • 보안 필터에 의해 차단
  • +
  • directory index 설정 없음
  • +
+

해결

+

파일 권한 확인: ls -la

+
+
+
+

413 Request Entity Too Large

+

업로드 크기 초과

+
+

원인

+
    +
  • 업로드 파일이 client_max_body_size 초과
  • +
  • SAM 기본값: 100MB
  • +
+

해결

+

client_max_body_size 200M;

+
+
+
+
+ + +
+

+ + 진단 명령어 사전 +

+
+
+# 설정 문법 검사 (가장 먼저 실행) +nginx -t # syntax ok / failed +docker exec sam-nginx-1 nginx -t # Docker 환경에서 + +# 전체 설정 출력 (include 파일 포함) +nginx -T + +# 에러 로그 실시간 모니터링 +tail -f /var/log/nginx/error.log +docker logs -f sam-nginx-1 # Docker 환경에서 + +# 엑세스 로그 확인 +tail -100 /var/log/nginx/access.log + +# Nginx 프로세스 상태 +ps aux | grep nginx + +# 설정 리로드 (무중단) +nginx -s reload +docker exec sam-nginx-1 nginx -s reload # Docker 환경에서
+ +
+

로그 읽는 법

+
+

access_log: IP - 시간 "요청" 상태코드 바이트 "Referer" "User-Agent"

+

error_log: 시간 [레벨] PID#TID: *연결번호 에러메시지, client: IP, server: 도메인

+

레벨: emerg > alert > crit > error > warn > notice > info

+
+
+
+
+ + +
+

+ + FAQ +

+
+
+ + Q1. 502 Bad Gateway가 발생했다. 어떻게 해야 하나? + +
+

1. docker ps로 컨테이너 실행 상태 확인

+

2. docker logs sam-api-1로 PHP-FPM 에러 확인

+

3. PHP-FPM이 죽었다면 docker restart sam-api-1

+

4. 반복된다면 PHP 메모리 제한(memory_limit) 확인

+
+
+
+ + Q2. 이미지가 표시되지 않는다. (깨진 이미지) + +
+

1. 브라우저 개발자 도구 → Network 탭에서 이미지 URL과 응답 코드 확인

+

2. 403이면 파일 권한 문제 → ls -la로 확인

+

3. 404면 경로 문제 → storage:link 심볼릭 링크 확인

+

4. MNG 테넌트 이미지면 /tenant-storage/ 프록시 설정 확인

+
+
+
+ + Q3. HTTPS 인증서 오류가 나타난다. + +
+

1. 인증서 만료 확인: openssl x509 -in sam.kr.crt -noout -dates

+

2. 와일드카드 인증서가 해당 도메인을 커버하는지 확인

+

3. 인증서 파일 경로가 /etc/nginx/ssl/에 올바르게 마운트되었는지 확인

+

4. nginx -t로 설정 문법 오류 확인

+
+
+
+ + Q4. 파일 업로드가 실패한다. (413 에러) + +
+

1. Nginx client_max_body_size 확인 (SAM 기본값: 100M)

+

2. PHP upload_max_filesizepost_max_size 확인

+

3. 외부 Nginx와 내부 Nginx 모두에서 크기 제한을 확인해야 함

+

4. Laravel의 validation 규칙에서도 파일 크기 제한 확인

+
+
+
+ + Q5. Nginx 설정을 변경했는데 반영이 안 된다. + +
+

1. nginx -t로 문법 오류 확인 (오류 시 리로드 실패)

+

2. nginx -s reload로 설정 리로드

+

3. Docker 볼륨 마운트 확인 (docker-compose.yml에서 설정 파일 경로)

+

4. 브라우저 캐시 때문에 안 보일 수 있음 → Ctrl+Shift+R (강력 새로고침)

+
+
+
+ + +
+ Nginx 핵심 정리 인포그래픽 +
+

Nginx의 6가지 핵심 역할 — SAM 프로젝트의 수문장

+ +
+

핵심 정리

+

+ Nginx는 SAM 프로젝트의 "수문장"이다. + 외부에서 들어오는 모든 요청을 받아 SSL 암호화를 처리하고, + 5개 도메인을 각각의 서비스로 안내하며, + 수상한 요청을 걸러내고, + 정적 파일을 빠르게 서빙한다. + 문제가 생기면 nginx -t로 설정을 검사하고, + error.log를 확인하는 것이 첫 단계다. +

+
+
+
+
+ +
+
+
+ + +
+ + +
+ + + + + +@include('components.academy-glossary', ['domain' => 'nginx-encyclopedia']) +@endsection diff --git a/resources/views/components/academy-glossary.blade.php b/resources/views/components/academy-glossary.blade.php index 8911a2e0..12b6b355 100644 --- a/resources/views/components/academy-glossary.blade.php +++ b/resources/views/components/academy-glossary.blade.php @@ -1,7 +1,7 @@ {{-- Academy Glossary Tooltip Component @include('components.academy-glossary', ['domain' => 'fire-shutter']) - 도메인: fire-shutter | it-planning | server-knowledge | frontend-dev | docker-environment | backend-dev | web-basics | env-management + 도메인: fire-shutter | it-planning | server-knowledge | frontend-dev | docker-environment | backend-dev | web-basics | env-management | nginx-encyclopedia --}} @push('styles') @@ -350,6 +350,29 @@ "멀티레포": "하나의 프로젝트를 여러 독립 저장소로 나누어 관리하는 전략. SAM은 mng/api/react 3개로 운영.", "Pint": "Laravel 공식 코드 포맷터. PHP 코드 스타일을 자동으로 정리해주는 도구. Pre-commit에서 자동 실행." }; +@elseif($domain === 'nginx-encyclopedia') +window.__GLOSSARY_DATA['nginx-encyclopedia'] = { + "Nginx": "고성능 웹 서버이자 리버스 프록시. 이벤트 기반 비동기 처리로 적은 메모리로 수만 개 동시 접속을 처리한다.", + "리버스 프록시": "클라이언트 요청을 받아 적절한 내부 서비스로 전달하는 중간 서버. SAM에서 외부 Nginx가 이 역할을 한다.", + "server 블록": "Nginx 설정에서 하나의 도메인(가상 호스트)을 정의하는 설정 단위. server_name으로 도메인을 지정한다.", + "location 블록": "server 블록 안에서 URL 경로별 처리 규칙을 정의하는 설정 단위. 정규식이나 접두사로 매칭한다.", + "upstream": "Nginx가 요청을 전달할 백엔드 서버 그룹을 정의하는 디렉티브. 로드 밸런싱에 사용한다.", + "proxy_pass": "클라이언트 요청을 다른 서버(백엔드)로 전달하는 디렉티브. HTTP 프록시 방식으로 동작한다.", + "FastCGI": "웹 서버와 애플리케이션(PHP 등) 사이의 고속 통신 프로토콜. CGI의 성능 개선 버전이다.", + "fastcgi_pass": "PHP-FPM 등 FastCGI 서버에 요청을 전달하는 디렉티브. proxy_pass와 비슷하지만 FastCGI 프로토콜을 사용한다.", + "try_files": "요청된 URI에 대해 파일 존재 여부를 순서대로 확인하는 디렉티브. 없으면 마지막 인자(Laravel의 index.php)로 전달한다.", + "SSL/TLS": "인터넷 통신을 암호화하여 데이터를 보호하는 보안 프로토콜. HTTPS의 기반 기술이다.", + "ssl_protocols": "허용할 TLS 버전을 지정하는 디렉티브. SAM은 TLSv1.2와 TLSv1.3만 허용한다.", + "HTTP/2": "HTTP 프로토콜의 2세대 버전. 하나의 TCP 연결에서 여러 요청을 동시에 처리하는 멀티플렉싱을 지원한다.", + "WebSocket": "서버와 클라이언트 간 양방향 실시간 통신을 지원하는 프로토콜. Upgrade 헤더로 HTTP 연결을 전환한다.", + "HSTS": "HTTP Strict Transport Security. 브라우저에게 항상 HTTPS로 접속하도록 강제하는 보안 헤더.", + "X-Frame-Options": "웹 페이지가 iframe에 삽입되는 것을 제어하는 보안 헤더. 클릭재킹(clickjacking) 공격을 방지한다.", + "client_max_body_size": "클라이언트가 업로드할 수 있는 최대 요청 본문 크기를 설정하는 디렉티브. SAM은 100MB로 설정되어 있다.", + "expires": "응답에 캐시 만료 시간을 설정하는 디렉티브. 30d는 30일간 브라우저 캐시에 보관하라는 의미이다.", + "access_log": "클라이언트의 요청 기록을 저장하는 로그 파일. IP, 요청 경로, 응답 코드, User-Agent 등이 기록된다.", + "error_log": "Nginx 오류 및 경고를 기록하는 로그 파일. 설정 오류, 백엔드 연결 실패 등이 기록된다.", + "nginx -t": "Nginx 설정 파일의 문법 오류를 검사하는 명령어. 설정 변경 후 반드시 실행하여 오류를 확인해야 한다." +}; @elseif($domain === 'env-management') window.__GLOSSARY_DATA['env-management'] = { ".env": "환경 변수를 저장하는 설정 파일. DB 접속 정보, API 키 등 환경마다 달라지는 값을 관리한다.",