<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Servlet Path on Joonlog</title><link>https://joonlog.github.io/tags/servlet-path/</link><description>Recent content in Servlet Path on Joonlog</description><generator>Hugo -- gohugo.io</generator><language>ko-kr</language><lastBuildDate>Sat, 04 Oct 2025 09:00:00 +0900</lastBuildDate><atom:link href="https://joonlog.github.io/tags/servlet-path/index.xml" rel="self" type="application/rss+xml"/><item><title>Docker Tomcat에서 Context Path 설정 무시 TroubleShooting</title><link>https://joonlog.github.io/p/docker-tomcat%EC%97%90%EC%84%9C-context-path-%EC%84%A4%EC%A0%95-%EB%AC%B4%EC%8B%9C-troubleshooting/</link><pubDate>Sat, 04 Oct 2025 09:00:00 +0900</pubDate><guid>https://joonlog.github.io/p/docker-tomcat%EC%97%90%EC%84%9C-context-path-%EC%84%A4%EC%A0%95-%EB%AC%B4%EC%8B%9C-troubleshooting/</guid><description>&lt;blockquote&gt;
&lt;p&gt;IDE 환경에서는 잘 작동하던 Context Path 설정이 Docker Tomcat에서는 무시되어 발생한 문제
Tomcat의 WAR 파일 배포 메커니즘과 appBase/docBase 개념을 이해해야 해결 가능한 이슈&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="환경"&gt;환경
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Java 1.8&lt;/li&gt;
&lt;li&gt;Tomcat 9.0.41&lt;/li&gt;
&lt;li&gt;Spring 기반 CMS&lt;/li&gt;
&lt;li&gt;Docker로 Tomcat WAS 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="문제-상황"&gt;문제 상황
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;빌드한 app.war를 Docker Tomcat으로 배포 후 &lt;code&gt;/app/index.do&lt;/code&gt; 접근 시 무한 리다이렉트 발생
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/app/index.do&lt;/code&gt; → &lt;code&gt;/index.html&lt;/code&gt; → &lt;code&gt;/app/index.do&lt;/code&gt; 반복&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;context path가 &lt;code&gt;/&lt;/code&gt;로 설정됐어야 하는데 &lt;code&gt;app&lt;/code&gt;으로 설정되어 있음
&lt;ul&gt;
&lt;li&gt;server.xml 설정이 무시됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;초기 설정
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dockerfile&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-docker" data-lang="docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app.war &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/webapps/app.war&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; server.xml &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conf/server.xml&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;server.xml&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;Host&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;appBase=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;webapps&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;unpackWARs=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;autoDeploy=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Context&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;docBase=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;app&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;reloadable=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;false&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/Host&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="에러-분석"&gt;에러 분석
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;무한 리다이렉트 발생 이유
&lt;ul&gt;
&lt;li&gt;애플리케이션에 index.do를 받을 수 있는 2개의 컨트롤러 존재
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;@RequestMapping(&amp;quot;/index.do&amp;quot;)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;index.html로 리다이렉트&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@RequestMapping(&amp;quot;/{siteId}/index.do&amp;quot;)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;실제 사이트 로직 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;브라우저에서 &lt;code&gt;/app/index.do&lt;/code&gt;로 접근 시 2번으로 가야하는데 계속 1번으로만 처리됨
&lt;ul&gt;
&lt;li&gt;context path가 &lt;code&gt;/&lt;/code&gt;가 아닌 &lt;code&gt;app&lt;/code&gt;으로 되어 있다는 증거
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;/app/index.do&lt;/code&gt;로 요청&lt;/li&gt;
&lt;li&gt;Tomcat이 context path 제거 → Servlet Path = &lt;code&gt;/index.do&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Spring이 &lt;code&gt;/index.do&lt;/code&gt; 매핑 찾음 → 1번 컨트롤러 매칭&lt;/li&gt;
&lt;li&gt;&lt;code&gt;redirect:/index.html&lt;/code&gt; 반환&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/index.html&lt;/code&gt; 내부에 &lt;code&gt;location.href = &amp;quot;/app/index.do&amp;quot;&lt;/code&gt; 스크립트&lt;/li&gt;
&lt;li&gt;1번으로 돌아가서 무한 루프&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;server.xml 설정이 무시된 이유
&lt;ul&gt;
&lt;li&gt;Tomcat의 WAR 배포 우선순위
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;autoDeploy=&amp;quot;true&amp;quot;&lt;/code&gt; 설정 시 webapps 디렉토리 자동 스캔&lt;/li&gt;
&lt;li&gt;&lt;code&gt;app.war&lt;/code&gt; 발견 → 파일명 기준으로 자동 배포
&lt;ul&gt;
&lt;li&gt;Context Path = &lt;code&gt;/app&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;server.xml의 &lt;code&gt;&amp;lt;Context&amp;gt;&lt;/code&gt; 설정은 자동 배포에 의해 무시됨&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IDE 환경과의 차이가 발생한 이유
&lt;ul&gt;
&lt;li&gt;IDE
&lt;ol&gt;
&lt;li&gt;UI에서 Context Path를 &lt;code&gt;/&lt;/code&gt;로 직접 지정 가능&lt;/li&gt;
&lt;li&gt;WAR 파일명과 무관하게 IDE 내부적으로 Context 설정 파일 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Docker Tomcat
&lt;ol&gt;
&lt;li&gt;WAR 파일명이 Context Path를 결정&lt;/li&gt;
&lt;li&gt;Tomcat 자체 규칙만 적용&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="해결-방법-1"&gt;해결 방법 1
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;war 파일을 ROOT.war로 배포&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;가장 간단하고 확실한 방법&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context Path가 ROOT.war 파일명에 따라 &lt;code&gt;/&lt;/code&gt;로 설정됨&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dockerfile&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-docker" data-lang="docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app.war &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/webapps/ROOT.war&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;/app/index.do로 요청&lt;/li&gt;
&lt;li&gt;Tomcat이 context path 제거 → Servlet Path = &lt;code&gt;/app/index.do&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Spring이 &lt;code&gt;/{siteId}/index.do&lt;/code&gt; 패턴 매칭 → 2번 컨트롤러 매칭 (siteId=app)&lt;/li&gt;
&lt;li&gt;정상 동작&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="해결-방법-2"&gt;해결 방법 2
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Context xml 파일 설정
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;app.war 파일명을 유지하면서 Context Path를 변경하는 방법&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;appBase: Tomcat이 애플리케이션을 찾는 작업 공간&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기본: &lt;code&gt;webapps&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;docBase: 특정 애플리케이션의 실제 파일 위치&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tomcat 9 보안 정책: appBase 내부의 WAR를 docBase로 지정하면 무시됨&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;war 파일을 appBase와 다른곳으로 이동&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dockerfile&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-docker" data-lang="docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# WAR를 appBase 밖에 배치&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; mkdir -p &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/apps&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app.war &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/apps/app.war&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Context 설정 파일 생성&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; mkdir -p &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conf/Catalina/localhost&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; ROOT.xml &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conf/Catalina/localhost/ROOT.xml&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# server.xml 수정 (autoDeploy 비활성화)&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; server.xml &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CATALINA_HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/conf/server.xml&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ROOT.xml&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;Context&lt;/span&gt; &lt;span class="na"&gt;docBase=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;${catalina.home}/apps/app.war&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;server.xml&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;Server&lt;/span&gt; &lt;span class="na"&gt;port=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;8005&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;shutdown=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SHUTDOWN&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Service&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Catalina&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Connector&lt;/span&gt; &lt;span class="na"&gt;port=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;8080&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;protocol=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;HTTP/1.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;connectionTimeout=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;20000&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;redirectPort=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;8443&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;URIEncoding=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Engine&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Catalina&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;defaultHost=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Host&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;appBase=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;webapps&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;unpackWARs=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;autoDeploy=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;false&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;deployOnStartup=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/Host&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/Engine&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/Service&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/Server&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;동작 순서&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;server.xml&lt;/code&gt;의 &lt;code&gt;autoDeploy=&amp;quot;false&amp;quot;&lt;/code&gt; 설정으로 webapps의 WAR자동 배포 비활성화&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server.xml&lt;/code&gt;의 &lt;code&gt;deployOnStartup=&amp;quot;true&amp;quot;&lt;/code&gt; 설정으로 Context XML 파일 읽기 활성화&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ROOT.xml&lt;/code&gt; → Context Path &lt;code&gt;/&lt;/code&gt; 지정
&lt;ul&gt;
&lt;li&gt;파일명이 ROOT이므로 &lt;code&gt;/&lt;/code&gt;로 설정됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ROOT.xml&lt;/code&gt;의 &lt;code&gt;docBase=&amp;quot;/opt/tomcat/apps/app.war&amp;quot;&lt;/code&gt; 설정으로 appBase 밖의 경로에서 war참조&lt;/li&gt;
&lt;li&gt;Tomcat이 &lt;code&gt;apps/app.war&lt;/code&gt;를 &lt;code&gt;webapps/ROOT/&lt;/code&gt;로 압축 해제 후 실행&lt;/li&gt;
&lt;li&gt;정상 동작&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="정리"&gt;정리
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Tomcat의 WAR 배포 규칙&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;WAR 파일명: Context Path&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ROOT.war -&amp;gt; /
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;admin.war -&amp;gt; /admin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;my-app.war -&amp;gt; /my-app
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;server.xml의 Context 설정은 비권장&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;autoDeploy=&amp;quot;true&amp;quot;&lt;/code&gt; 환경에서는 대부분 무시됨&lt;/li&gt;
&lt;li&gt;설정 변경 시 Tomcat 전체 재시작 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;appBase / docBase&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;appBase 내부의 WAR를 docBase로 지정하면 Tomcat 9에서 무시됨&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;appBase&lt;/th&gt;
&lt;th&gt;docBase&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;정의&lt;/td&gt;
&lt;td&gt;Tomcat의 작업 공간&lt;/td&gt;
&lt;td&gt;앱의 소스 위치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;기본값&lt;/td&gt;
&lt;td&gt;&lt;code&gt;webapps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;내용&lt;/td&gt;
&lt;td&gt;WAR + 압축 해제된 코드&lt;/td&gt;
&lt;td&gt;WAR 또는 디렉토리 경로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;자동 배포&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context Path / Servlet Path&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;애플리케이션 라우팅 로직이 Servlet Path를 기준으로 설계되었다면 Context Path가 라우팅에 영향을 줄 수 있음&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;요청 URL: /app/index.do&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Context Path: /
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Servlet Path: /app/index.do
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;요청 URL: /app/index.do&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Context Path: /app
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Servlet Path: /index.do
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="참고"&gt;참고
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://tomcat.apache.org/tomcat-9.0-doc/config/context.html" target="_blank" rel="noopener"
&gt;https://tomcat.apache.org/tomcat-9.0-doc/config/context.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://tomcat.apache.org/tomcat-9.0-doc/config/host.html#Automatic_Application_Deployment" target="_blank" rel="noopener"
&gt;https://tomcat.apache.org/tomcat-9.0-doc/config/host.html#Automatic_Application_Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html" target="_blank" rel="noopener"
&gt;https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>