TIL - 20260804

juni·2026년 8월 4일

TIL

목록 보기
422/468

0804 인프라/DevOps 운영 심화 (3/N): Nginx, Reverse Proxy와 HTTPS 기본


✅ 1. Nginx란 무엇인가?

  • Nginx는 웹 서버이자 Reverse Proxy 서버입니다.
  • 정적 파일을 제공하거나, 사용자의 요청을 백엔드 애플리케이션 서버로 전달하는 역할을 합니다.
  • 운영 서버에서는 Node.js/NestJS 앱을 직접 인터넷에 노출하기보다 Nginx를 앞단에 두는 경우가 많습니다.
사용자 브라우저
  ↓
Nginx
  ↓
NestJS / Next.js / API Server

➕ 1-1. Nginx를 쓰는 이유

  • 80/443 포트로 외부 요청을 받을 수 있습니다.
  • HTTPS 인증서를 적용할 수 있습니다.
  • 백엔드 앱의 실제 포트를 숨길 수 있습니다.
  • 여러 서비스로 요청을 나눌 수 있습니다.
  • 정적 파일, 이미지, 프론트 빌드 파일을 제공할 수 있습니다.
  • 요청 크기, timeout, gzip, cache 같은 운영 설정을 제어할 수 있습니다.
Nginx 없이:
사용자 → Node.js 앱 직접 접근

Nginx 사용:
사용자 → Nginx → Node.js 앱

장점:
보안, HTTPS, 라우팅, 운영 설정 관리가 쉬워짐

✅ 2. Web Server와 Reverse Proxy 차이

  • Nginx는 상황에 따라 웹 서버로도 쓰고 Reverse Proxy로도 씁니다.
역할의미예시
Web Server파일을 직접 응답HTML, CSS, JS, 이미지
Reverse Proxy요청을 다른 서버로 전달/api 요청을 NestJS로 전달

➕ 2-1. Web Server 예시

사용자:
https://example.com

Nginx:
dist/index.html, JS, CSS 파일 제공

➕ 2-2. Reverse Proxy 예시

사용자:
https://api.example.com/admin/consults

Nginx:
localhost:3000에서 실행 중인 NestJS로 요청 전달
  • 프론트엔드를 S3 + CloudFront로 배포한다면 Nginx는 주로 백엔드 API 앞단에서 Reverse Proxy 역할을 합니다.
  • 프론트까지 같은 서버에서 배포한다면 Nginx가 정적 파일 제공도 할 수 있습니다.

✅ 3. Reverse Proxy란 무엇인가?

  • Reverse Proxy는 클라이언트 요청을 대신 받아 내부 서버로 전달하는 구조입니다.
  • 사용자는 내부 서버의 실제 주소와 포트를 모릅니다.
  • Nginx가 앞에서 요청을 받고, 뒤에 있는 애플리케이션 서버로 넘깁니다.
Client
  ↓
https://api.example.com
  ↓
Nginx :443
  ↓
NestJS localhost:3000

➕ 3-1. 왜 직접 Node.js를 노출하지 않을까?

Node.js 앱 직접 노출:
포트 관리 어려움
HTTPS 적용 번거로움
정적 파일/압축/캐시 처리 약함
운영 설정 분산
여러 앱 라우팅 어려움

➕ 3-2. Nginx 앞단 구조

외부 공개:
80, 443

내부 앱:
3000, 3001, 4000 등

Nginx:
외부 요청을 내부 앱으로 전달
  • 운영에서는 외부에 80/443만 열고, 내부 앱 포트는 외부에서 직접 접근하지 못하게 하는 것이 좋습니다.

✅ 4. 기본 Nginx 설정 구조

  • Nginx 설정은 보통 server 블록과 location 블록으로 구성됩니다.
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
    }
}

➕ 4-1. server 블록

server:
특정 도메인과 포트에 대한 설정

예:
example.com의 80 포트 요청 처리

➕ 4-2. location 블록

location:
요청 경로별 처리 방식

예:
/api 요청은 백엔드로 전달
/admin 요청은 관리자 앱으로 전달
/static 요청은 정적 파일 제공

➕ 4-3. proxy_pass

proxy_pass:
요청을 넘길 내부 서버 주소

예:
proxy_pass http://localhost:3000;
  • server_name은 도메인 기준입니다.
  • location은 URL 경로 기준입니다.
  • proxy_pass는 실제 요청을 넘길 대상입니다.

✅ 5. NestJS API 서버 Reverse Proxy 예시

  • NestJS 백엔드가 localhost:3000에서 실행 중이라면 Nginx는 외부 요청을 해당 포트로 넘길 수 있습니다.
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

➕ 5-1. 주요 header 의미

Header의미
Host원래 요청 도메인
X-Real-IP실제 사용자 IP
X-Forwarded-For프록시를 거친 IP 목록
X-Forwarded-Protohttp/https 여부

➕ 5-2. 왜 header가 필요할까?

  • 백엔드가 실제 사용자 IP를 알아야 할 수 있습니다.
  • HTTPS 여부를 판단해야 할 수 있습니다.
  • 로그, 보안, rate limit, redirect 처리에 필요합니다.
  • NestJS에서 req.ip, protocol, secure cookie 설정에 영향을 줄 수 있습니다.
사용자 IP:
운영 로그, 중복 IP 확인, rate limit

X-Forwarded-Proto:
HTTPS 판단, secure cookie, redirect

✅ 6. HTTPS란 무엇인가?

  • HTTPS는 HTTP 통신을 암호화한 방식입니다.
  • 사용자의 브라우저와 서버 사이 데이터가 암호화되어 전송됩니다.
  • 로그인, 관리자 페이지, 상담 신청, 개인정보 입력이 있는 서비스에서는 HTTPS가 필수입니다.
HTTP:
암호화 없음

HTTPS:
TLS 인증서 기반 암호화

➕ 6-1. HTTPS가 필요한 이유

  • 로그인 정보 보호
  • 상담 신청 전화번호/이름 보호
  • 관리자 쿠키 보호
  • 브라우저 보안 경고 방지
  • SEO와 사용자 신뢰 향상
  • 결제/인증/외부 API 연동 요구사항 충족
HTTP로 상담 신청:
이름, 전화번호가 암호화 없이 전송될 수 있음

HTTP로 관리자 로그인:
관리자 세션 탈취 위험 증가
  • 개인정보를 다루는 서비스에서 HTTPS는 선택이 아니라 기본입니다.

✅ 7. TLS 인증서와 Let's Encrypt

  • HTTPS를 쓰려면 TLS 인증서가 필요합니다.
  • Let's Encrypt는 무료 TLS 인증서를 발급해주는 서비스입니다.
  • 보통 Certbot을 사용해 Nginx에 인증서를 적용합니다.
도메인 준비
  ↓
Nginx 80 포트 연결
  ↓
Certbot 인증서 발급
  ↓
Nginx HTTPS 설정 자동 반영
  ↓
인증서 자동 갱신 설정

➕ 7-1. Certbot 예시

sudo apt update
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d api.example.com

➕ 7-2. 인증서 갱신 테스트

sudo certbot renew --dry-run
  • Let's Encrypt 인증서는 보통 자동 갱신을 설정합니다.
  • 갱신 실패 시 HTTPS가 만료되어 서비스 접속에 문제가 생길 수 있습니다.

✅ 8. HTTP에서 HTTPS로 리다이렉트

  • 운영에서는 HTTP 요청을 HTTPS로 자동 리다이렉트하는 것이 좋습니다.
server {
    listen 80;
    server_name api.example.com;

    return 301 https://$host$request_uri;
}

➕ 8-1. HTTPS server 블록

server {
    listen 443 ssl;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

➕ 8-2. 흐름

http://api.example.com
  ↓
301 redirect
  ↓
https://api.example.com
  ↓
Nginx 443
  ↓
NestJS localhost:3000
  • 사용자가 http://로 접속해도 자동으로 https://로 이동하게 해야 합니다.
  • 관리자 페이지와 API 모두 HTTPS 기준으로 맞추는 것이 좋습니다.

✅ 9. Nginx 설정 테스트와 reload

  • Nginx 설정을 수정한 뒤에는 바로 재시작하지 말고 설정 테스트를 먼저 해야 합니다.

➕ 9-1. 설정 테스트

sudo nginx -t

정상 예시:

syntax is ok
test is successful

➕ 9-2. 설정 반영

sudo systemctl reload nginx

➕ 9-3. 상태 확인

sudo systemctl status nginx
  • reload는 설정을 부드럽게 다시 읽습니다.
  • 설정 오류가 있는 상태에서 무작정 restart하면 Nginx가 내려갈 수 있습니다.
  • 항상 nginx -t → reload 순서가 안전합니다.

✅ 10. Nginx 로그 확인

  • Nginx 문제를 볼 때는 access log와 error log를 확인합니다.

➕ 10-1. Access Log

sudo tail -f /var/log/nginx/access.log
  • 어떤 요청이 들어왔는지 확인할 수 있습니다.
  • 상태 코드, 요청 경로, IP 등을 볼 수 있습니다.

➕ 10-2. Error Log

sudo tail -f /var/log/nginx/error.log
  • proxy 연결 실패, 설정 문제, 권한 문제 등을 확인할 수 있습니다.

➕ 10-3. 자주 보는 상태 코드

상태 코드의미
200성공
301/302리다이렉트
400잘못된 요청
401인증 필요
403접근 금지
404경로 없음
413요청 크기 초과
499클라이언트가 연결 끊음
502upstream 서버 오류
504upstream timeout
  • Nginx에서 502가 나면 백엔드 앱이 꺼져 있거나 proxy 대상 포트가 틀린 경우가 많습니다.
  • 413은 파일 업로드나 큰 요청에서 자주 만납니다.

✅ 11. 502 Bad Gateway 원인

  • Nginx 운영 중 가장 자주 보는 에러 중 하나가 502입니다.
  • Nginx가 백엔드 서버로 요청을 넘기려 했지만 실패한 상태입니다.
사용자
  ↓
Nginx 정상
  ↓
백엔드 연결 실패
  ↓
502 Bad Gateway

➕ 11-1. 주요 원인

백엔드 앱이 꺼져 있음
백엔드 포트가 다름
proxy_pass 주소가 틀림
백엔드가 crash 반복
방화벽/네트워크 문제
Docker 컨테이너 이름/포트 오류

➕ 11-2. 확인 순서

sudo systemctl status nginx
sudo tail -f /var/log/nginx/error.log
curl http://localhost:3000/health
pm2 status
docker compose ps
docker compose logs -f backend

➕ 11-3. 판단 기준

curl localhost:3000 실패:
백엔드 앱 문제

curl localhost:3000 성공:
Nginx proxy 설정 문제 가능

Nginx error.log에 connection refused:
백엔드 포트/실행 상태 문제
  • 502가 나오면 프론트 문제가 아니라 Nginx와 백엔드 연결 문제부터 봐야 합니다.

✅ 12. 413 Payload Too Large

  • 파일 업로드, 이미지 업로드, 엑셀 업로드에서 413이 발생할 수 있습니다.
  • Nginx의 기본 요청 크기 제한에 걸리는 경우입니다.

➕ 12-1. 설정 예시

server {
    listen 443 ssl;
    server_name api.example.com;

    client_max_body_size 20M;

    location / {
        proxy_pass http://localhost:3000;
    }
}

➕ 12-2. 주의할 점

Nginx 제한
백엔드 body parser 제한
파일 업로드 라이브러리 제한
S3 presigned upload 구조 여부
  • Nginx만 늘린다고 끝이 아닐 수 있습니다.
  • 백엔드의 request body limit도 함께 확인해야 합니다.
  • 큰 파일은 가능하면 서버를 거치지 않고 S3 presigned URL 업로드를 고려할 수 있습니다.

✅ 13. Timeout 설정

  • 백엔드 처리가 오래 걸리면 Nginx timeout에 걸릴 수 있습니다.
  • 엑셀 다운로드, 대량 조회, 외부 API 호출에서 발생할 수 있습니다.

➕ 13-1. 설정 예시

location / {
    proxy_pass http://localhost:3000;

    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
}

➕ 13-2. 주의할 점

timeout을 무작정 늘리는 것은 해결책이 아님
느린 API 원인 분석 필요
대용량 작업은 비동기 Job으로 분리
엑셀 Export는 ExportJob 구조 권장
  • timeout이 난다고 계속 시간을 늘리면 서버 자원을 오래 붙잡습니다.
  • 대용량 엑셀이나 오래 걸리는 작업은 Queue/Worker로 분리하는 것이 더 좋습니다.

✅ 14. WebSocket Proxy

  • WebSocket을 사용한다면 Nginx에서 Upgrade header를 처리해야 합니다.
  • 일반 HTTP proxy 설정만으로는 WebSocket 연결이 제대로 안 될 수 있습니다.
location /socket.io/ {
    proxy_pass http://localhost:3000;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

➕ 14-1. 필요한 경우

실시간 상담 알림
관리자 주문 상태 실시간 반영
작업 진행률 표시
ExportJob 진행 상태 실시간 표시

➕ 14-2. 점검할 것

Nginx Upgrade header
백엔드 WebSocket path
프론트 WebSocket URL
HTTPS 환경에서는 wss 사용
CORS 설정
로드밸런서 idle timeout
  • HTTPS 사이트에서는 WebSocket도 wss://를 사용해야 합니다.
  • ws://를 쓰면 브라우저에서 mixed content 문제가 날 수 있습니다.

✅ 15. CORS와 Nginx

  • CORS는 브라우저 보안 정책입니다.
  • 프론트 도메인과 API 도메인이 다르면 CORS 설정이 필요합니다.
프론트:
https://www.example.com

API:
https://api.example.com

브라우저:
다른 origin으로 판단

➕ 15-1. CORS는 어디서 처리할까?

권장:
백엔드 애플리케이션에서 명확히 처리

가능:
Nginx에서 header 추가

주의:
둘 다 중복 처리하면 꼬일 수 있음

➕ 15-2. NestJS CORS 예시

app.enableCors({
  origin: ['https://www.example.com', 'https://admin.example.com'],
  credentials: true,
});

➕ 15-3. 주의할 점

credentials: true 사용 시 origin: "*" 불가
쿠키 기반 인증이면 SameSite/Secure 설정 확인
OPTIONS preflight 처리 필요
로컬 개발 origin도 별도 허용
  • CORS 문제는 Nginx 문제처럼 보일 수 있지만 실제로는 백엔드 CORS 설정인 경우가 많습니다.
  • 쿠키 인증을 쓰면 CORS와 cookie 설정을 같이 봐야 합니다.

✅ 16. Cookie와 HTTPS

  • 관리자 로그인이나 고객 인증 흐름에서 쿠키를 사용한다면 HTTPS 설정이 중요합니다.
  • Secure 쿠키는 HTTPS에서만 전송됩니다.

➕ 16-1. 쿠키 옵션

httpOnly:
JavaScript에서 접근 불가

secure:
HTTPS에서만 전송

sameSite:
cross-site 요청에서 쿠키 전송 기준

domain:
쿠키 적용 도메인

path:
쿠키 적용 경로

➕ 16-2. 운영 기준

운영:
httpOnly true
secure true
sameSite 정책 명확히
HTTPS 필수

로컬:
secure false가 필요할 수 있음
localhost 기준 별도 설정

➕ 16-3. X-Forwarded-Proto 중요성

Nginx가 HTTPS 종료
  ↓
백엔드로는 HTTP 요청처럼 보일 수 있음
  ↓
X-Forwarded-Proto로 원래 HTTPS 요청임을 전달
  • 백엔드가 proxy 뒤에 있을 때는 trust proxy 설정도 함께 봐야 합니다.
  • secure cookie가 안 붙거나 로그인 유지가 안 되면 HTTPS, CORS, cookie, proxy header를 같이 확인해야 합니다.

✅ 17. 같은 도메인 경로 분리 vs 서브도메인 분리

  • 프론트와 API를 어떻게 나눌지 정해야 합니다.

➕ 17-1. 서브도메인 분리

고객:
https://www.example.com

관리자:
https://admin.example.com

API:
https://api.example.com

장점:

역할이 명확함
배포 분리 쉬움
CORS 정책 명확
관리자와 고객 분리 쉬움

단점:

CORS 설정 필요
쿠키 domain/sameSite 고려 필요
인증 정책 복잡 가능

➕ 17-2. 같은 도메인 경로 분리

프론트:
https://example.com

API:
https://example.com/api

장점:

CORS 부담 적음
쿠키 처리 단순
사용자 입장에서 도메인 단순

단점:

Nginx location 설정 중요
프론트 라우팅과 API 경로 충돌 주의
배포 분리 복잡 가능
  • 작은 서비스는 경로 분리도 괜찮습니다.
  • 고객/관리자/API를 명확히 분리하려면 서브도메인 구조가 관리하기 좋습니다.

✅ 18. /api 경로 Reverse Proxy 예시

  • 같은 도메인에서 프론트와 API를 함께 운영한다면 /api 경로만 백엔드로 넘길 수 있습니다.
server {
    listen 443 ssl;
    server_name example.com;

    root /var/www/frontend/dist;
    index index.html;

    location /api/ {
        proxy_pass http://localhost:3000/api/;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

➕ 18-1. 주의할 점

proxy_pass 뒤 slash 여부 주의
프론트 라우팅과 /api 경로 충돌 방지
백엔드 global prefix와 맞추기
SPA fallback이 API 요청을 먹지 않게 하기
  • /api 요청은 백엔드로 가야 하고, 프론트 라우팅 fallback으로 빠지면 안 됩니다.
  • location 순서와 경로를 명확히 해야 합니다.

✅ 19. 정적 프론트 제공 예시

  • S3/CloudFront를 쓰지 않고 서버에서 직접 프론트 정적 파일을 제공할 수도 있습니다.
server {
    listen 80;
    server_name example.com;

    root /var/www/frontend/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

➕ 19-1. SPA fallback

사용자 /products/1 직접 접속
  ↓
실제 파일 없음
  ↓
Nginx가 index.html 반환
  ↓
React Router가 /products/1 처리

➕ 19-2. 주의할 점

index.html 캐시 길게 잡지 않기
assets 캐시 전략 분리
배포 시 이전 파일 정리 기준 필요
CloudFront보다 글로벌 캐시 약함
  • 작은 내부 관리자 페이지는 Nginx 정적 제공도 충분할 수 있습니다.
  • 고객 트래픽이 많거나 이미지/정적 파일이 많으면 S3 + CloudFront가 더 적합합니다.

✅ 20. Gzip/Brotli 압축

  • JS, CSS, HTML 같은 텍스트 파일은 압축하면 전송 용량이 줄어듭니다.
  • Nginx에서 gzip을 켤 수 있습니다.
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1024;

➕ 20-1. 압축에 적합한 파일

HTML
CSS
JavaScript
JSON
SVG
XML

➕ 20-2. 이미 압축된 파일

JPG
PNG
WebP
AVIF
ZIP
PDF
  • 이미 압축된 이미지 파일은 gzip 효과가 거의 없습니다.
  • 프론트 번들 파일에는 gzip 또는 Brotli 압축이 체감 성능에 도움이 됩니다.

✅ 21. 보안 Header 기본

  • Nginx에서 기본 보안 header를 추가할 수 있습니다.
  • 너무 복잡한 CSP는 처음부터 무리하지 말고, 기본적인 것부터 적용하면 됩니다.
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

➕ 21-1. HSTS

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

➕ 21-2. HSTS 주의

HTTPS가 완전히 안정된 뒤 적용
includeSubDomains는 모든 서브도메인 HTTPS 준비 필요
잘못 적용하면 HTTP 접속 복구가 어려울 수 있음
  • HSTS는 강력하지만 조심해야 합니다.
  • 서브도메인 중 HTTPS가 준비되지 않은 곳이 있으면 문제가 될 수 있습니다.

✅ 22. 방화벽과 포트 관리

  • 운영 서버에서는 외부에 필요한 포트만 열어야 합니다.
  • 일반적으로 외부 공개는 80, 443만 열고, 백엔드 앱 포트는 내부에서만 접근하게 둡니다.
외부 공개:
80
443

외부 비공개:
3000
5432
6379

➕ 22-1. UFW 예시

sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 22
sudo ufw enable
sudo ufw status

➕ 22-2. 주의할 포트

PostgreSQL 5432 외부 공개 금지
Redis 6379 외부 공개 금지
Node 앱 3000 외부 직접 공개 지양
관리자용 내부 도구 포트 공개 금지
  • DB와 Redis가 외부에 열려 있으면 매우 위험합니다.
  • Nginx만 외부 요청을 받고, 내부 앱/DB는 서버 내부 네트워크에서만 접근하게 해야 합니다.

✅ 23. PM2와 Nginx 조합

  • Node.js 앱은 PM2로 실행하고, Nginx가 앞에서 요청을 받아 PM2 앱으로 전달하는 구조가 흔합니다.
Client
  ↓
Nginx :443
  ↓
PM2로 실행 중인 NestJS :3000

➕ 23-1. PM2 상태 확인

pm2 status

➕ 23-2. 로그 확인

pm2 logs

➕ 23-3. 재시작

pm2 restart togethermall-api
  • 502가 나면 Nginx만 보지 말고 PM2 앱이 살아 있는지도 확인해야 합니다.
  • PM2 앱 이름을 명확하게 지정해두면 운영이 편합니다.

✅ 24. Docker Compose와 Nginx 조합

  • 백엔드를 Docker 컨테이너로 실행한다면 Nginx가 컨테이너 포트로 proxy할 수 있습니다.
  • Nginx를 호스트에 설치할 수도 있고, Nginx도 컨테이너로 실행할 수도 있습니다.

➕ 24-1. 호스트 Nginx → Docker Backend

Nginx:
host에 설치

Backend:
Docker container, host port 3000으로 노출

proxy_pass:
http://localhost:3000

➕ 24-2. Docker Nginx → Docker Backend

Nginx:
Docker container

Backend:
Docker container

proxy_pass:
http://backend:3000

➕ 24-3. 주의

Nginx가 어디에서 실행되는지에 따라 proxy_pass host가 달라짐
호스트 Nginx는 localhost:3000
컨테이너 Nginx는 service name:3000
포트 publish 여부 확인
Docker network 확인
  • 0803에서 정리한 DB host 문제와 비슷합니다.
  • 실행 위치에 따라 localhost가 의미하는 대상이 달라집니다.

✅ 25. 운영 배포 시 체크리스트

➕ 25-1. Nginx 설정 체크리스트

  1. server_name이 실제 도메인과 맞는가?
  2. 80 포트에서 HTTPS로 리다이렉트되는가?
  3. 443 SSL 인증서 경로가 맞는가?
  4. proxy_pass 대상 포트가 실제 백엔드와 맞는가?
  5. X-Forwarded-* header가 설정되어 있는가?
  6. WebSocket이 필요하면 Upgrade header가 있는가?
  7. 파일 업로드가 있으면 client_max_body_size가 적절한가?
  8. SPA 정적 제공 시 try_files 설정이 있는가?

➕ 25-2. HTTPS 체크리스트

  1. 인증서가 정상 발급되었는가?
  2. 인증서 자동 갱신이 되는가?
  3. certbot renew --dry-run이 성공하는가?
  4. HTTP 접속 시 HTTPS로 이동하는가?
  5. 브라우저에서 보안 경고가 없는가?
  6. API 요청이 https://로 호출되는가?
  7. WebSocket 사용 시 wss://로 연결되는가?
  8. secure cookie가 정상 전송되는가?

➕ 25-3. 장애 대응 체크리스트

  1. 502 발생 시 백엔드 앱 상태를 확인했는가?
  2. curl localhost:3000/health가 성공하는가?
  3. Nginx error log를 확인했는가?
  4. PM2 또는 Docker 로그를 확인했는가?
  5. 413 발생 시 Nginx와 백엔드 body limit을 같이 확인했는가?
  6. 504 발생 시 느린 API 또는 timeout 설정을 확인했는가?
  7. CORS 문제인지 Nginx 문제인지 구분했는가?
  8. 최근 배포에서 Nginx 설정 변경이 있었는가?

✅ 26. AI에게 Nginx/HTTPS 문제를 물어볼 때 좋은 질문법

  • Nginx 문제는 도메인, 설정 파일, 백엔드 실행 방식, 로그가 있어야 정확히 분석할 수 있습니다.
  • “502가 나요”만 말하면 원인이 너무 많습니다.

➕ 26-1. 좋은 질문 예시

Ubuntu 서버에서 Nginx를 Reverse Proxy로 사용해 NestJS API를 운영하고 있어.

상황:
1. 도메인은 api.example.com
2. Nginx는 host에 설치되어 있음
3. NestJS는 PM2로 localhost:3000에서 실행 중
4. HTTPS는 Let's Encrypt + Certbot 사용
5. 브라우저에서 https://api.example.com 접속 시 502 Bad Gateway가 발생함
6. curl http://localhost:3000/health 결과는 아래와 같음
7. sudo nginx -t 결과는 아래와 같음
8. /var/log/nginx/error.log 최근 로그는 아래와 같음

아래 정보를 기준으로 원인을 좁히고 확인 순서를 알려줘.
답변은:
- 가장 가능성 높은 원인
- 확인 명령어
- Nginx 설정 수정 후보
- 백엔드/PM2 확인 항목
- 재발 방지 체크리스트
순서로 정리해줘.

➕ 26-2. AI 답변 검증 기준

  1. 백엔드가 PM2인지 Docker인지 확인하는가?
  2. Nginx가 host인지 container인지 구분하는가?
  3. curl localhost:3000으로 backend 상태를 먼저 확인하는가?
  4. nginx -t 후 reload하라고 하는가?
  5. Nginx error log를 보라고 하는가?
  6. proxy header와 proxy_pass를 점검하는가?
  7. HTTPS 인증서와 80→443 리다이렉트를 구분하는가?
  8. 위험한 방화벽/DB 포트 공개를 제안하지 않는가?

📌 요약

  • Nginx는 웹 서버이자 Reverse Proxy 서버로, 운영 환경에서 사용자 요청을 받아 백엔드 앱으로 전달하거나 정적 파일을 제공하는 역할을 합니다.
  • Node.js/NestJS 앱을 직접 외부에 노출하기보다 Nginx를 앞단에 두면 HTTPS, 포트 관리, proxy header, timeout, 업로드 제한, 라우팅 관리가 쉬워집니다.
  • Reverse Proxy 구조에서는 외부에는 80/443만 열고, 백엔드 앱 포트인 3000, DB 포트 5432, Redis 포트 6379는 외부에 공개하지 않는 것이 기본입니다.
  • HTTPS는 로그인, 관리자 페이지, 상담 신청처럼 개인정보가 오가는 서비스에서 필수이며, Let's Encrypt와 Certbot으로 무료 인증서를 발급하고 자동 갱신을 설정할 수 있습니다.
  • Nginx 설정을 바꾼 뒤에는 반드시 sudo nginx -t로 문법을 확인하고 sudo systemctl reload nginx로 반영하는 순서가 안전합니다.
  • 502 Bad Gateway는 Nginx가 백엔드에 연결하지 못하는 경우가 많으므로, 백엔드 실행 상태, 포트, proxy_pass, PM2/Docker 로그를 먼저 확인해야 합니다.
  • 파일 업로드에서 413이 발생하면 Nginx의 client_max_body_size뿐 아니라 백엔드 body parser 제한도 함께 확인해야 합니다.
  • WebSocket을 쓰는 경우 Nginx에서 Upgrade, Connection header를 설정해야 하며, HTTPS 환경에서는 wss:// 연결을 사용해야 합니다.
  • 프론트와 API를 서브도메인으로 나눌지, 같은 도메인의 /api 경로로 나눌지는 CORS, 쿠키, 배포 구조를 고려해 선택해야 합니다.
  • Nginx/HTTPS 문제를 AI에게 물어볼 때는 Nginx 실행 위치, 백엔드 실행 방식, 도메인, 설정 파일, nginx -t, backend health check, error log를 함께 제공해야 정확한 원인 분석이 가능합니다.

0개의 댓글