Categories
웹개발/Tomcat
Tomcat context path 설정 방법과 배포 시 주의사항
context path가 뭔가
Tomcat에 애플리케이션을 올리면 URL 앞에 /앱이름이 붙는다. 예를 들어 http://localhost:8080/myapp/main.do에서 /myapp 부분이 context path다. 이 경로를 원하는 값으로 바꾸거나 아예 없애려고 할 때 Tomcat context path 설정을 찾게 된다. 문제는 설정할 수 있는 위치가 한 곳이 아니라는 점이다. WAR 파일명, server.xml, 개별 context.xml까지 방법이 나뉘고, 각각 적용 시점과 우선순위가 다르다.
경로가 안 맞으면 화면이 통째로 404가 나거나, 정적 리소스만 안 불러와지는 문제로 이어진다. 그래서 배포 전에 어느 방식으로 잡을지 정해 두는 게 좋다. 한 서버에 앱 하나만 올리느냐, 여러 앱을 같이 운영하느냐에 따라 적절한 방법도 달라진다.
설정 방법 비교
| 방법 | 설정 위치 | 특징 | 적합한 상황 |
|---|---|---|---|
| WAR 파일명 | webapps/ 에 배포하는 파일명 | 파일명이 곧 context path | 가장 단순, 표준 배포 |
| ROOT 배포 | webapps/ROOT | context path가 / (없음) | 도메인 루트로 서비스 |
| server.xml Context | conf/server.xml | 경로·docBase 직접 지정 | webapps 밖 경로 배포 |
| 개별 context.xml | conf/Catalina/localhost/ | 앱별 파일로 분리 관리 | 여러 앱 개별 관리 |
네 방법 모두 결과적으로 같은 일을 하지만, 설정을 어디에 두느냐가 다르다. 아래에서 하나씩 본다.
방법 1. WAR 파일명으로 정하기
1. 가장 단순하고 권장되는 방식
Tomcat은 기본적으로 webapps 폴더에 올라온 WAR 파일명(또는 폴더명)을 context path로 쓴다. myapp.war를 배포하면 경로는 /myapp가 된다.
# myapp.war 배포 → http://localhost:8080/myapp
cp myapp.war /usr/local/tomcat/webapps/
# 경로를 /board 로 하고 싶으면 파일명을 바꿔 배포
cp myapp.war /usr/local/tomcat/webapps/board.war
# → http://localhost:8080/board
이 방식이 가장 단순하고 설정 파일을 안 건드려도 돼서 표준 배포에 적합하다. 운영에서는 파일명을 함부로 바꾸면 기존 URL과 어긋날 수 있으니, 변경 전에 외부에 노출된 경로가 있는지 먼저 확인한다.
2. 경로에 계층을 주고 싶을 때 (## 표기)
파일명에 ##을 넣으면 버전 구분이나 다단계 경로를 표현할 수 있다. 예를 들어 같은 앱의 여러 버전을 구분할 때 쓴다.
# myapp##v1.war → context path는 /myapp (v1은 버전 식별용)
cp myapp##v1.war /usr/local/tomcat/webapps/
# → http://localhost:8080/myapp
# 다단계 경로가 필요하면 # 을 사용 (Tomcat 버전에 따라 동작 차이 있음)
# board#admin.war → /board/admin
## 뒤는 버전 식별자로 취급돼 context path에는 포함되지 않는다. 병행 배포(parallel deployment) 같은 상황에서 쓰이지만, 표기 규칙이 Tomcat 버전마다 차이가 있을 수 있으므로 운영 적용 전 해당 버전 문서로 확인하는 것이 좋다.
3. ROOT로 배포해서 경로 없애기
context path 없이 http://도메인/ 바로 서비스하려면 ROOT로 배포한다. webapps/ROOT 폴더가 context path가 비어 있는(/) 애플리케이션이다.
# 기존 ROOT 백업 후 교체 (운영은 반드시 백업)
mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT_bak
# 내 앱을 ROOT로 배포
cp -r myapp /usr/local/tomcat/webapps/ROOT
# → http://localhost:8080/
기본 ROOT에는 Tomcat 안내 페이지가 들어 있다. 운영에서 교체할 때는 기존 ROOT를 백업하고, 되돌릴 수 있게 해 둔다. ROOT로 띄우면 경로 접두어가 사라지므로, 앱 내부에서 절대경로로 작성한 링크가 있다면 영향을 받는지 함께 확인한다.
방법 2. server.xml에서 Context 지정
1. webapps 밖 경로의 앱을 띄울 때
webapps 밖의 경로에 있는 앱을 띄우거나, 경로와 실제 디렉토리를 분리하고 싶을 때 server.xml의 <Host> 안에 <Context>를 직접 적는다.
<!-- conf/server.xml 의 <Host> 태그 안 -->
<Host name="localhost" appBase="webapps" ...>
<Context path="/board"
docBase="/data/apps/myapp"
reloadable="false" />
</Host>
path가 URL 경로, docBase가 실제 파일이 있는 물리 경로다. 위 예는 /data/apps/myapp에 있는 앱을 /board 경로로 띄운다.
2. server.xml 직접 수정이 권장되지 않는 이유
server.xml에 직접 Context를 넣는 방식은 Tomcat 공식 문서에서 권장하지 않는다. 이유는 두 가지다. 첫째, 이 파일을 고치면 Tomcat을 재기동해야 반영된다. 운영 중 무중단으로 컨텍스트만 바꾸기 어렵다. 둘째, server.xml은 Tomcat 전체 기동에 관여하는 파일이라 사소한 오타 하나가 전체 서버 기동 실패로 이어질 수 있다. 그래서 가능하면 다음 방법(개별 context.xml)을 쓰는 편이 안전하다. 기존 운영 서버에 이미 server.xml Context가 박혀 있다면, 함부로 옮기지 말고 영향 범위를 확인한 뒤 정비한다.
방법 3. 개별 context.xml로 분리
1. 앱별 파일로 관리하기
앱마다 설정을 분리해 관리하려면 conf/Catalina/localhost/ 아래에 {경로}.xml 파일을 둔다. 파일명이 context path가 된다.
<!-- conf/Catalina/localhost/board.xml -->
<!-- 파일명 board.xml → context path는 /board -->
<Context docBase="/data/apps/myapp"
reloadable="false" />
이 방식은 server.xml을 건드리지 않아 안전하고, 앱별로 파일이 나뉘어 관리가 깔끔하다. 여러 앱을 운영하는 서버라면 이 방법이 유지보수에 유리하다. 파일을 추가/수정하면 해당 앱 컨텍스트가 다시 로드된다(버전에 따라 동작 차이가 있을 수 있으니 확인한다).
2. 다단계 경로는 파일명 규칙으로
/board/admin처럼 다단계 경로가 필요하면 파일명에 #을 쓴다. board#admin.xml은 /board/admin 경로가 된다.
# conf/Catalina/localhost/board#admin.xml
# → context path: /board/admin
이 규칙도 Tomcat 버전에 따라 차이가 있을 수 있으므로, 적용 후 배포 로그에서 실제 경로를 확인하는 습관을 들이는 것이 좋다.
우선순위와 충돌 주의
같은 경로를 여러 곳에서 정의하면 충돌한다. 예를 들어 webapps/board.war도 있고 conf/Catalina/localhost/board.xml도 있으면 어느 쪽이 적용되는지 헷갈린다. 설정은 한 가지 방식으로 통일하는 것이 가장 안전하다. 특히 운영 서버에서는 누군가 과거에 server.xml에 Context를 박아 둔 걸 모르고 WAR 파일명만 바꿔서 "분명 바꿨는데 경로가 그대로"인 상황이 생긴다. 경로가 의도대로 안 잡히면 WAR 파일명, server.xml, 개별 context.xml 세 군데를 모두 확인한다.
로그로 확인하는 방법
배포 후 경로가 제대로 잡혔는지는 기동 로그에서 확인할 수 있다. catalina.out이나 콘솔에 컨텍스트 배포 메시지가 남는다.
# 컨텍스트 배포 로그 확인 (경로는 환경에 맞게)
tail -f /usr/local/tomcat/logs/catalina.out
# Deploying web application 같은 메시지에서 경로 확인
grep -i deploy /usr/local/tomcat/logs/catalina.out
배포된 컨텍스트 경로가 로그에 찍히므로, 의도한 경로와 맞는지 비교한다. 404가 난다면 실제 배포된 경로와 브라우저가 요청한 경로가 다른 경우가 대부분이다. 로그에 찍힌 경로가 맞다면 문제는 Tomcat이 아니라 앱 내부 링크나 앞단 웹서버(Apache) 설정일 가능성이 높다.
실무에서 자주 하는 실수
- context path를 바꾸고 나서 애플리케이션 내부의 정적 리소스 경로(JSP의 CSS/JS 링크)를 그대로 둬서 404가 나는 경우. 경로를 절대경로로 쓸 때는 context path 변경의 영향을 받는다.
- server.xml에 Context를 넣고 재기동을 안 해서 반영이 안 된 경우.
- WAR 파일명과 압축 해제된 폴더가 둘 다 남아 옛 버전이 뜨는 경우. 배포 전 기존 폴더 정리를 확인한다.
- ROOT 교체 후 기본 ROOT 백업을 안 해서 되돌리기 어려워진 경우.
- 같은 경로를 두 가지 방식으로 동시에 정의해 어느 쪽이 적용되는지 모호해진 경우.
FAQ
Q1. context path를 / (루트)로 만들려면 어떻게 하나요?
앱을 webapps/ROOT로 배포하면 context path가 비어서 도메인 루트로 서비스된다. 기존 ROOT는 백업해 둔다.
Q2. server.xml과 context.xml 중 어디서 설정하는 게 좋나요?
가능하면 server.xml 직접 수정은 피하고, conf/Catalina/localhost/ 아래 개별 xml이나 WAR 파일명 방식을 쓴다. server.xml은 재기동이 필요하고 실수 시 영향이 크다.
Q3. 경로를 바꿨는데 적용이 안 됩니다.
여러 곳에 설정이 중복됐을 가능성이 높다. WAR 파일명, server.xml의 Context, 개별 context.xml을 모두 확인한다. server.xml을 고쳤다면 재기동했는지도 본다.
Q4. context path를 바꾸니 CSS·JS가 404 납니다.
JSP 등에서 경로를 잘못 작성한 경우다. ${pageContext.request.contextPath}를 붙여 context path 변경에 영향받지 않게 한다.
Q5. docBase와 path는 무엇이 다른가요?
path는 URL 경로(브라우저가 입력하는 부분), docBase는 실제 파일이 있는 물리 디렉토리다. 둘을 분리하면 webapps 밖 경로의 앱도 띄울 수 있다.
정리
Tomcat context path 설정은 방법이 여러 가지지만 우선순위는 분명하다. 단순 배포는 WAR 파일명으로 맞추는 게 가장 깔끔하고, 루트 서비스는 ROOT 배포, webapps 밖 경로나 앱별 관리는 conf/Catalina/localhost/ 개별 xml을 쓴다. server.xml 직접 수정은 재기동과 영향 범위 때문에 가급적 피한다. 경로가 의도대로 안 잡히면 설정이 여러 곳에 중복됐는지부터 확인하고, 배포 로그에서 실제 컨텍스트 경로를 점검한다. Tomcat 버전에 따라 기본 동작이나 파일명 규칙이 다를 수 있으니, 운영 반영 전에는 테스트 환경에서 먼저 확인하는 것이 안전하다.