본문으로 건너뛰기
Advertisement

server.xml 구조 분석

server.xml은 Tomcat의 핵심 설정 파일로, 서버의 전체 계층 구조를 정의합니다. 이 파일을 이해하면 포트 설정, 가상 호스트, 애플리케이션 컨텍스트를 자유롭게 제어할 수 있습니다.


전체 계층 구조

server.xml은 XML 트리 구조로 Tomcat의 컴포넌트 계층을 표현합니다.

<Server>                          <!-- 최상위: JVM 프로세스 하나 -->
<Service> <!-- 커넥터 묶음 + 엔진 -->
<Connector port="8080" .../> <!-- 요청 수신 포트 -->
<Connector port="8009" .../> <!-- AJP 포트 (선택) -->
<Engine name="Catalina"> <!-- 요청 처리 엔진 -->
<Host name="localhost"> <!-- 가상 호스트 -->
<Context path="/" /> <!-- 웹 애플리케이션 -->
</Host>
</Engine>
</Service>
</Server>

각 컴포넌트 역할

컴포넌트역할핵심 속성
ServerJVM 인스턴스 전체를 대표port (종료 명령 포트), shutdown
Service커넥터 집합 + 엔진name
Connector네트워크 요청 수신 (HTTP/AJP)port, protocol, maxThreads
Engine요청을 Host로 라우팅name, defaultHost
Host가상 호스트 (도메인 기반 분기)name, appBase
Context웹 애플리케이션 경로 매핑path, docBase

Server 엘리먼트

<Server port="8005" shutdown="SHUTDOWN">
속성설명기본값
port종료 명령 수신 포트8005
shutdown종료 명령 문자열SHUTDOWN

보안 권고: port="-1"로 설정하면 종료 포트를 비활성화할 수 있습니다. 원격 종료 명령 취약점 방지에 유용합니다.

<!-- 종료 포트 비활성화 (프로덕션 권장) -->
<Server port="-1" shutdown="SHUTDOWN">

Service 엘리먼트

<Service name="Catalina">
<!-- Connector들과 Engine이 여기에 포함됨 -->
</Service>

하나의 Server 안에 여러 Service를 등록할 수 있지만, 일반적으로 하나의 "Catalina" Service를 사용합니다.


Engine 엘리먼트

<Engine name="Catalina" defaultHost="localhost">
속성설명
name엔진 식별자 (로그에 사용)
defaultHost매핑되는 Host가 없을 때 사용할 기본 호스트
jvmRoute로드밸런서 클러스터 환경에서 세션 끈기(Sticky Session) 식별자
<!-- 클러스터 환경에서 jvmRoute 설정 -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

Host 엘리먼트

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
속성설명기본값
name가상 호스트 이름 (도메인 매칭)
appBase애플리케이션 기본 디렉터리webapps
unpackWARsWAR 파일 자동 압축 해제true
autoDeploy런타임 중 WAR 자동 배포true
deployOnStartup시작 시 appBase 자동 스캔true

다중 가상 호스트 설정

<Engine name="Catalina" defaultHost="localhost">

<!-- 기본 호스트 -->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log"
suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b"/>
</Host>

<!-- 추가 가상 호스트 -->
<Host name="api.example.com" appBase="/var/www/api"
unpackWARs="true" autoDeploy="false">
<Alias>api2.example.com</Alias> <!-- 별칭 -->
</Host>

<Host name="admin.example.com" appBase="/var/www/admin"
unpackWARs="true" autoDeploy="false">
</Host>

</Engine>

Context 엘리먼트

Context는 특정 웹 애플리케이션을 URL 경로에 매핑합니다. server.xml보다는 conf/Catalina/localhost/앱이름.xml 파일로 분리하는 것이 권장됩니다.

<!-- server.xml에 직접 등록 (비권장) -->
<Context path="/myapp" docBase="/var/www/myapp" reloadable="true"/>

<!-- 권장: conf/Catalina/localhost/myapp.xml -->

별도 Context 파일 방식 (권장)

<!-- conf/Catalina/localhost/myapp.xml -->
<Context docBase="/var/www/myapp"
path="/myapp"
reloadable="false"
crossContext="false">

<!-- JNDI 데이터소스 -->
<Resource name="jdbc/myDB"
auth="Container"
type="javax.sql.DataSource"
maxTotal="100"
maxIdle="30"
maxWaitMillis="10000"
username="dbuser"
password="dbpass"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb?useSSL=false"/>
</Context>
속성설명기본값
pathURL 컨텍스트 경로"" (ROOT)
docBase실제 파일 경로
reloadable클래스 변경 시 자동 리로드false
crossContext다른 컨텍스트 접근 허용false

프로덕션 주의: reloadable="true"는 개발 환경에서만 사용합니다. 운영 환경에서는 성능 저하를 유발합니다.


GlobalNamingResources

전역 JNDI 리소스(데이터소스, 메일 세션 등)를 정의합니다.

<GlobalNamingResources>
<!-- 사용자 인증 DB (기본 제공) -->
<Resource name="UserDatabase"
auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"/>

<!-- 글로벌 JDBC 데이터소스 -->
<Resource name="jdbc/globalDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://db-host:3306/mydb"
username="appuser"
password="secret"
maxTotal="50"
maxIdle="10"/>
</GlobalNamingResources>

Realm — 인증 설정

Realm은 사용자 인증 방법을 정의합니다.

<!-- 파일 기반 인증 (tomcat-users.xml) -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>

<!-- JDBC 기반 인증 -->
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/auth_db"
connectionName="auth_user"
connectionPassword="auth_pass"
userTable="users"
userNameCol="user_name"
userCredCol="user_pass"
userRoleTable="user_roles"
roleNameCol="role_name"/>

완성된 server.xml 예시 (프로덕션)

<?xml version="1.0" encoding="UTF-8"?>
<Server port="-1" shutdown="SHUTDOWN">

<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"/>
</GlobalNamingResources>

<Service name="Catalina">

<!-- HTTP/1.1 커넥터 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200"
minSpareThreads="10"
acceptCount="100"
enableLookups="false"
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressibleMimeType="text/html,text/xml,text/plain,text/css,application/json"/>

<Engine name="Catalina" defaultHost="localhost">

<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="false">

<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b %D"/>

<!-- 에러 처리 밸브 -->
<Valve className="org.apache.catalina.valves.ErrorReportValve"
showReport="false"
showServerInfo="false"/>

</Host>
</Engine>
</Service>
</Server>

Summary

컴포넌트핵심 설정주의사항
Serverport="-1" (보안)종료 포트 비활성화 권장
HostautoDeploy="false"프로덕션에서 자동 배포 비활성화
Context별도 XML 파일 권장reloadable="false" (운영)
EnginejvmRoute클러스터 Sticky Session 필수
RealmLockOutRealm 래핑무차별 대입 공격 방어
Advertisement