[Tomcat] Virtual Hosting (가상 호스팅)


 [ Tomcat 공식문서 한글번역 링크 ]


[ 준비환경 ]

- 이 안내서에서는 개발용 호스트에 두개의 호스트 이름(aaa.co.kr, bbb.co.kr) 가 있다고 가정한다.

- 또한 하나의 Tomcat 인스턴스를 실행한다고 가정하며, $CATALINA_HOME 은 Tomcat 이 설치된 위치를 나타낸다. (ex: /usr/local/tomcat)

- 이 안내서에서는 유닉스 스타일의 경로 구분자와 명령어를 사용하며, Windows 를 사용하는 경우 이에 맞게 적절히 수정해서 사용한다.


[ ★ 작성자 내용 추가 ★ ]

- 아래의 공식 문서의 모든 사항을 작업하지 않더라도 동작은 된다.

- 공식문서 내용 끝나고 추가적인 설명과 실습을 하단에 기재함.



[ Webapps 디렉토리 ]

- 각 가상 호스트를 위한 디렉토리를 생성한다.

mkdir $CATALINA_HOME/aaaapps
mkdir $CATALINA_HOME/bbbapps



[ server.xml ]

- 가장 간단한 설정으로 server.xml 파일의 Engine 부분을 다음과 같이 수정한다.

<Engine name="Catalina" defaultHost="aaa.co.kr">
    <Host name="aaa.co.kr" appBase="aaaapps"/>
    <Host name="bbb.co.kr" appBase="bbbapps"/>
</Engine>

- 각 호스트의 appBase 하위의 디렉토리 구조는 서로 겹치지 않아야 한다.

Engine 및 Host 요소의 다른 속성에 대한 정보는 해당 문서를 참고한다.


1004lucifer

[ Context 구성 ]

1. 일반적인 규칙

- Context 는 일반적으로 appBase 디렉토리 하위에 위치한다.

- 예를 들어 war 파일을 이용해 aaa.co.kr 호스트에서 foobar 컨텍스트를 배포하려면 $CATALINA_HOME/aaaapps/foobar.war 경로에 war 파일을 위치 시킨다.

- ren 의 기본 ROOT (/) 컨텍스트는 아래의 2개 방법중에 한가지 방법으로 배포된다.
 1) WAR 파일 방법: $CATALINA_HOME/aaaapps/ROOT.war
 2) 디렉토리 방법: $CATALINA_HOME/aaaapps/ROOT

- 참고: <Context>의 docBase 속성은 <Host>의 appBase 속성과 동일하면 안된다.


2. context.xml - 접근 방법 #1

- 컨텍스트 내부에 META-INF 디렉토리를 생성한 다음, context.xml 파일에 컨텍스트 내용을 정의한다.
- ex: $CATALINA_HOME/aaaapps/ROOT/META-INF/context.xml

- 이렇게 하면 WAR 파일을 배포하는 경우 배포가 더 쉬워진다.


3. context.xml - 접근 방법 #2

- 다음과 같이 가상 호스팅에 대한 구조를 $CATALINA_HOME/conf/Catalina 아래에 생성한다.

mkdir $CATALINA_HOME/conf/Catalina/aaa.co.kr
mkdir $CATALINA_HOME/conf/Catalina/bbb.co.kr

- 여기서 마지막 디렉토리 이름인 Catalina 는 Engine 요소의 name 속성을 나타낸다.

- 이제 기본 웹 애플리케이션을 위해 다음 파일을 추가한다.

$CATALINA_HOME/conf/Catalina/aaa.co.kr/ROOT.xml
$CATALINA_HOME/conf/Catalina/bbb.co.kr/ROOT.xml

- 각 호스트에 대해 Tomcat Manager WEB_Application 을 사용하려면 여기에도 추가해야 한다.

cd $CATALINA_HOME/conf/Catalina
cp localhost/manager.xml aaa.co.kr/
cp localhost/manager.xml bbb.co.kr/


4. host 별 기본값

- conf/context.xmlconf/web.xml 에서 보여지는 기본값을 호스트별 XML 디렉토리에 context.xml.defaultweb.xml.default 라는 이름의파일에 새로운 값을 기술하여 기본값을 덮어쓸 수 있다.

- 위 예제를 따라 가상호스트 ren 에 배포된 모든 WEB_Application 의 기본값을 커스텀 하려면 $CATALINA_HOME/conf/Catalina/aaa.co.kr/web.xml.default 를 사용할 수 있다.


5. 추가정보

- Context 요소의 다른 속성에 대한 설정은 해당 문서를 참고.


참조
 - https://tomcat.apache.org/tomcat-11.0-doc/virtual-hosting-howto.html



[ ★ 작성자 내용 추가 ★ ]

- 위 내용의 디렉토리 생성부분은 Tomcat 기동 시 모두 자동으로 디렉토리 생성해 주기에 일부러 생성해줄 필요는 없다.

- 필수 작업은 server.xml 설정과 Context 디렉토리 생성만 해주면 된다.
- Context 설정이 추가적으로 필요한경우 conf/Catalina/{도메인명}/context.xml 파일을 생성 후 해당 파일에 설정해주면 된다.


[ 실습 ]

[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # 현재 디렉토리 확인 (Tomcat 설치 디렉토리)
[1004lucifer@rhel8 tomcat]$ pwd
/usr/local/tomcat
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # 현재 디렉토리 내용 확인
[1004lucifer@rhel8 tomcat]$ ls -al
total 144
drwxr-xr-x. 9 1004lucifer 1004lucifer 220 Jan 24 20:55 .
drwxr-xr-x. 13 root root 145 Jan 23 03:43 ..
drwxr-xr-x. 2 1004lucifer 1004lucifer 4096 Dec 21 03:11 bin
-rw-r--r--. 1 1004lucifer 1004lucifer 21643 Dec 5 15:19 BUILDING.txt
drwxr-xr-x. 3 1004lucifer 1004lucifer 256 Jan 23 20:21 conf
-rw-r--r--. 1 1004lucifer 1004lucifer 6330 Dec 5 15:19 CONTRIBUTING.md
drwxr-xr-x. 2 1004lucifer 1004lucifer 4096 Dec 5 15:19 lib
-rw-r--r--. 1 1004lucifer 1004lucifer 61666 Dec 5 15:19 LICENSE
drwxr-xr-x. 2 1004lucifer 1004lucifer 4096 Jan 24 20:54 logs
-rw-r--r--. 1 1004lucifer 1004lucifer 2401 Dec 5 15:19 NOTICE
-rw-r--r--. 1 1004lucifer 1004lucifer 3370 Dec 5 15:19 README.md
-rw-r--r--. 1 1004lucifer 1004lucifer 6631 Dec 5 15:19 RELEASE-NOTES
-rw-r--r--. 1 1004lucifer 1004lucifer 16577 Dec 5 15:19 RUNNING.txt
drwxr-xr-x. 2 1004lucifer 1004lucifer 30 Dec 5 15:19 temp
drwxr-xr-x. 7 1004lucifer 1004lucifer 81 Jan 23 03:44 webapps
drwxr-xr-x. 3 1004lucifer 1004lucifer 22 Dec 21 03:12 work
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # conf/Catalina 디렉토리 내용 확인
[1004lucifer@rhel8 tomcat]$ ls -l conf/Catalina/
total 0
drwxrwxr-x. 2 1004lucifer 1004lucifer 22 Dec 19 11:50 localhost
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # hosts (aaa.co.kr, bbb.co.kr 도메인 설정 확인)
[1004lucifer@rhel8 tomcat]$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 aaa.co.kr bbb.co.kr
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # server.xml 파일 수정
[1004lucifer@rhel8 tomcat]$ vi conf/server.xml
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # server.xml 파일 내용 확인
[1004lucifer@rhel8 tomcat]$ cat conf/server.xml
... (생략)
</Realm>
<Host name="aaa.co.kr" appBase="aaaapps" />
<Host name="bbb.co.kr" appBase="bbbapps" />
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
... (생략)
</Host>
</Engine>
</Service>
</Server>
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # 톰캣 기동
[1004lucifer@rhel8 tomcat]$ ./bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/lib/jvm/jre-17
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # 톰캣 디렉토리 내부에 aaaapps, bbbapps 디렉토리 자동 생성됨
[1004lucifer@rhel8 tomcat]$ ll
total 144
drwxr-x---. 2 1004lucifer 1004lucifer 6 Jan 24 21:01 aaaapps
drwxr-x---. 2 1004lucifer 1004lucifer 6 Jan 24 21:01 bbbapps
drwxr-xr-x. 2 1004lucifer 1004lucifer 4096 Dec 21 03:11 bin
-rw-r--r--. 1 1004lucifer 1004lucifer 21643 Dec 5 15:19 BUILDING.txt
drwxr-xr-x. 3 1004lucifer 1004lucifer 256 Jan 24 20:59 conf
-rw-r--r--. 1 1004lucifer 1004lucifer 6330 Dec 5 15:19 CONTRIBUTING.md
drwxr-xr-x. 2 1004lucifer 1004lucifer 4096 Dec 5 15:19 lib
-rw-r--r--. 1 1004lucifer 1004lucifer 61666 Dec 5 15:19 LICENSE
drwxr-xr-x. 2 1004lucifer 1004lucifer 4096 Jan 24 21:01 logs
-rw-r--r--. 1 1004lucifer 1004lucifer 2401 Dec 5 15:19 NOTICE
-rw-r--r--. 1 1004lucifer 1004lucifer 3370 Dec 5 15:19 README.md
-rw-r--r--. 1 1004lucifer 1004lucifer 6631 Dec 5 15:19 RELEASE-NOTES
-rw-r--r--. 1 1004lucifer 1004lucifer 16577 Dec 5 15:19 RUNNING.txt
drwxr-xr-x. 2 1004lucifer 1004lucifer 30 Dec 5 15:19 temp
drwxr-xr-x. 7 1004lucifer 1004lucifer 81 Jan 23 03:44 webapps
drwxr-xr-x. 3 1004lucifer 1004lucifer 22 Dec 21 03:12 work
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # conf/Catalina 디렉토리 확인 (aaa.co.kr, bbb.co.kr 디렉토리 자동 생성됨)
[1004lucifer@rhel8 tomcat]$ ll conf/Catalina/
total 0
drwxr-x---. 2 1004lucifer 1004lucifer 6 Jan 24 21:01 aaa.co.kr
drwxr-x---. 2 1004lucifer 1004lucifer 6 Jan 24 21:01 bbb.co.kr
drwxrwxr-x. 2 1004lucifer 1004lucifer 22 Dec 19 11:50 localhost
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # aaa.co.kr 접속 (Context 가 없으니 404 에러 반환)
[1004lucifer@rhel8 tomcat]$ curl -v http://aaa.co.kr:8080/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to aaa.co.kr (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: aaa.co.kr:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 404
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 682
< Date: Sat, 25 Jan 2025 02:02:21 GMT
<
* Connection #0 to host aaa.co.kr left intact
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title>...(생략)</body></html>[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # bbb.co.kr 접속 (Context 가 없으니 404 에러 반환)
[1004lucifer@rhel8 tomcat]$ curl -v http://bbb.co.kr:8080/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to bbb.co.kr (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: bbb.co.kr:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 404
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 682
< Date: Sat, 25 Jan 2025 02:02:28 GMT
<
* Connection #0 to host bbb.co.kr left intact
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title>...(생략)</body></html>[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # ROOT (/) Context 생성해줌
[1004lucifer@rhel8 tomcat]$ mkdir aaaapps/ROOT
[1004lucifer@rhel8 tomcat]$ mkdir bbbapps/ROOT
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # ROOT 컨텍스트에 index.html 파일 생성
[1004lucifer@rhel8 tomcat]$ cat > aaaapps/ROOT/index.html
aaa.co.kr - index.html
^C
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ cat > bbbapps/ROOT/index.html
bbb.co.kr - index.html
^C
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # 생성된 html 파일 확인
[1004lucifer@rhel8 tomcat]$ ls -l *apps/ROOT/index.html
-rw-rw-r--. 1 1004lucifer 1004lucifer 25 Jan 24 21:03 aaaapps/ROOT/index.html
-rw-rw-r--. 1 1004lucifer 1004lucifer 25 Jan 24 21:03 bbbapps/ROOT/index.html
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # 해당 index.html 파일 내용 확인
[1004lucifer@rhel8 tomcat]$ cat aaaapps/ROOT/index.html
aaa.co.kr - index.html
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ cat bbbapps/ROOT/index.html
bbb.co.kr - index.html
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # aaa.co.kr 도메인 ROOT(/) Context 로 접속 (정상응답)
[1004lucifer@rhel8 tomcat]$ curl -v http://aaa.co.kr:8080/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to aaa.co.kr (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: aaa.co.kr:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200
< Accept-Ranges: bytes
< ETag: W/"25-1737770601467"
< Last-Modified: Sat, 25 Jan 2025 02:03:21 GMT
< Content-Type: text/html
< Content-Length: 25
< Date: Sat, 25 Jan 2025 02:04:56 GMT
<
aaa.co.kr - index.html
* Connection #0 to host aaa.co.kr left intact
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # bbb.co.kr 도메인 ROOT(/) Context 로 접속 (정상응답)
[1004lucifer@rhel8 tomcat]$ curl -v http://bbb.co.kr:8080/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to bbb.co.kr (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: bbb.co.kr:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200
< Accept-Ranges: bytes
< ETag: W/"25-1737770616078"
< Last-Modified: Sat, 25 Jan 2025 02:03:36 GMT
< Content-Type: text/html
< Content-Length: 25
< Date: Sat, 25 Jan 2025 02:05:03 GMT
<
bbb.co.kr - index.html
* Connection #0 to host bbb.co.kr left intact
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # aaa.co.kr 도메인에 test Context 생성
[1004lucifer@rhel8 tomcat]$ mkdir aaaapps/test
[1004lucifer@rhel8 tomcat]$ # index.html 파일 생성
[1004lucifer@rhel8 tomcat]$ cat > aaaapps/test/index.html
aaa.co.kr - test - index.html
^C
[1004lucifer@rhel8 tomcat]$ cat aaaapps/test/index.html
aaa.co.kr - test - index.html
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$
[1004lucifer@rhel8 tomcat]$ # aaa.co.kr 도메인의 /test 컨텍스트로 접속 (정상응답)
[1004lucifer@rhel8 tomcat]$ curl -v http://aaa.co.kr:8080/test/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to aaa.co.kr (127.0.0.1) port 8080 (#0)
> GET /test/ HTTP/1.1
> Host: aaa.co.kr:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200
< Accept-Ranges: bytes
< ETag: W/"32-1737770734810"
< Last-Modified: Sat, 25 Jan 2025 02:05:34 GMT
< Content-Type: text/html
< Content-Length: 32
< Date: Sat, 25 Jan 2025 02:05:51 GMT
<
aaa.co.kr - test - index.html
* Connection #0 to host aaa.co.kr left intact
[1004lucifer@rhel8 tomcat]$


댓글