Nginx + Tomcat 연동 아키텍처 설계
Nginx와 Tomcat을 연동하면 각자의 장점을 극대화할 수 있습니다. Nginx는 정적 파일 서빙과 SSL 종료를 담당하고, Tomcat은 Java 비즈니스 로직 처리에 집중합니다. 이 챕터에서는 실무에서 쓰이는 연동 아키텍처 패턴과 포트 구성을 다룹니다.
왜 Nginx + Tomcat을 함께 쓰는가
| 혼자 쓸 때의 한계 | Nginx + Tomcat 조합으로 해결 |
|---|---|
| Tomcat 단독: 정적 파일 처리 느림, SSL 관리 번거로움 | Nginx가 정적 파일 + SSL 처리 |
| Nginx 단독: Java 앱 실행 불가 | Tomcat이 서블릿/JSP/Spring 처리 |
| Tomcat 단독: 대량 동시 연결에 약함 | Nginx가 연결을 받아 Tomcat에 분산 |
기본 연동 아키텍처
단순 리버스 프록시 패턴
[클라이언트]
↓ HTTPS :443 / HTTP :80
[Nginx] ← SSL 종료, 정적 파일, 압축, 접근 제한
↓ HTTP :8080 (내부망)
[Tomcat] ← Java 서블릿, JSP, Spring MVC, REST API
↓
[DB / 내부 서비스]
흐름 설명:
- 클라이언트 → Nginx:443 (HTTPS)
- Nginx: SSL 복호화 후 정적 파일은 직접 응답
- Nginx: 동적 요청은 Tomcat:8080으로 프록시
- Tomcat: 비즈니스 로직 처리 후 응답 반환
- Nginx: 응답에 캐시/보안 헤더 추가 후 클라이언트에 전달
정적/동적 분리 서빙 패턴
[클라이언트]
↓
[Nginx :443]
├── /static/*, *.css, *.js, *.png → Nginx 직접 서빙 (파일 시스템)
├── /api/* → Tomcat :8080 (REST API)
└── /* → Tomcat :8080 (Spring MVC)
이 패턴은 Tomcat의 스레드를 정적 파일에 낭비하지 않아 처리량이 크게 향상됩니다.
포트 구성
표준 포트 구성
| 서버 | 포트 | 프로토콜 | 설명 |
|---|---|---|---|
| Nginx | 80 | HTTP | HTTPS 리다이렉트 |
| Nginx | 443 | HTTPS | 메인 서빙 포트 |
| Tomcat | 8080 | HTTP | Nginx → Tomcat 내부 통신 |
| Tomcat | 8009 | AJP | Apache 연동용 (사용 시) |
| Tomcat | 8005 | TCP | Tomcat 종료 명령 포트 |
방화벽 설정:
- 외부 허용: 80, 443 (Nginx)
- 외부 차단: 8080, 8009, 8005 (내부 전용)
보안 원칙: Tomcat 포트(8080)는 외부에 노출하지 않습니다. Nginx만 외부 포트를 열고, Tomcat은
localhost또는 내부망에서만 통신합니다.
Tomcat 수신 주소 제한
<!-- server.xml — 로컬호스트에서만 수신 -->
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"
redirectPort="8443"/>
연동 방식 비교
| 방식 | 설명 | 장점 | 단점 |
|---|---|---|---|
| HTTP 프록시 | proxy_pass http://tomcat:8080 | 설정 단순, 범용 | HTTP 오버헤드 |
| AJP 프록시 | ngx_http_ajp_module | 바이너리 효율 | Nginx 기본 미지원, Ghostcat 위험 |
| UNIX 소켓 | proxy_pass http://unix:/tmp/tomcat.sock | 프로세스 간 고속 통신 | 동일 서버 필수 |
현대적 권장: HTTP 프록시(proxy_pass http://) 방식. 설정이 단순하고 다양한 환경에서 동작합니다.
다중 Tomcat 인스턴스 구성
하나의 Nginx가 여러 Tomcat 인스턴스에 부하를 분산하는 패턴입니다.
[Nginx :443]
↓ upstream round-robin
├── Tomcat-1 :8080
├── Tomcat-2 :8081
└── Tomcat-3 :8082
이 패턴은 Ch8(로드 밸런싱)에서 자세히 다루며, 이 챕터에서는 단일 Tomcat 연동에 집중합니다.
실제 서버 디렉터리 구조 예시
/var/www/
├── myapp/ ← 정적 파일 (Nginx가 직접 서빙)
│ ├── index.html
│ ├── static/
│ │ ├── css/
│ │ ├── js/
│ │ └── images/
│ └── uploads/ ← 사용자 업로드 파일
/opt/tomcat/latest/
├── webapps/
│ └── ROOT/ ← Spring Boot WAR or 서블릿 앱
│ └── WEB-INF/
└── logs/
/etc/nginx/
├── nginx.conf
└── sites-available/
└── myapp.conf ← 연동 설정
설정 파일 개요
# /etc/nginx/sites-available/myapp.conf (개요)
upstream tomcat_backend {
server 127.0.0.1:8080;
}
server {
listen 443 ssl;
server_name example.com;
# 정적 파일 — Nginx 직접 서빙
location /static/ {
root /var/www/myapp;
expires 1y;
}
# 동적 요청 — Tomcat으로 프록시
location / {
proxy_pass http://tomcat_backend;
# ... 헤더 설정 ...
}
}
다음 챕터들에서 각 설정을 상세히 다룹니다.
Summary
| 항목 | 권장 설정 |
|---|---|
| 외부 공개 포트 | 80 (HTTP→HTTPS 리다이렉트), 443 (HTTPS) |
| Tomcat 수신 주소 | address="127.0.0.1" (로컬만) |
| 연동 방식 | HTTP 프록시 (proxy_pass http://) |
| 정적 파일 | Nginx 직접 서빙 (파일 시스템) |
| 동적 요청 | Tomcat으로 프록시 |