Apache Tomcat 9 설치
1. 설치
다음의 명령어로 설치한다.
sudo apt install tomcat9
2. 설치 후 작업
2.1. 압축 설정
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" compression="on" compressibleMimeType= "text/html,text/xml,application/xml,text/plain,text/css,text/javascript,application/javascript" compressionMinSize="2048" redirectPort="8443" />
2.2. 데이타베이스 설정
2.2.1. JDBC 드라이버 다운로드
PostgreSQL JDBC 4.2 Driver 및 xdbc 라이브러리를 /var/lib/tomcat9/lib
로 다운로드 하여야 한다.
이 글을 쓰는 시점에서 파일명은 postgresql-42.3.2.jar, xdbc.0.2.0.0.jar 와 같다.
파일을 다운로드 받은 디렉토리에서 다음과 같은 명령어를 실행한다.
sudo mv postgresql-42.3.2.jar /var/lib/tomcat9/lib/ sudo mv xdbc.0.2.0.0.jar /var/lib/tomcat9/lib/ sudo chown tomcat:tomcat /var/lib/tomcat9/lib/postgresql-42.3.2.jar sudo chown tomcat:tomcat /var/lib/tomcat9/lib/xdbc.0.2.0.0.jar
2.2.2. server.xml 파일 변경
/var/lib/tomcat9/conf/server.xml
파일의 </GlobalNamingResources>
바로 앞에 다음과 같은 설정을 추가한다.
<Resource name="jdbc/graha" auth="Container" type="javax.sql.DataSource" driverClassName="kr.xdbc.driver.GenericDriver" url="xdbc:jdbc:postgresql://localhost/graha|jdbc:postgresql://localhost/graha_backup" username="graha" password="changeit!" maxTotal="100" maxIdle="5" maxWaitMillis="-1"/>
/var/lib/tomcat9/conf/server.xml
파일은 다음과 같이 열어야 한다.
sudo vi /var/lib/tomcat9/conf/server.xml
2.2.3. context.xml 파일 변경
/var/lib/tomcat9/conf/context.xml
파일의 </Context>
바로 앞에 다음과 같은 설정을 추가한다.
<ResourceLink global="jdbc/graha" name="jdbc/graha" type="javax.sql.DataSource"/>
/var/lib/tomcat9/conf/context.xml
파일은 다음과 같이 열어야 한다.
sudo vi /var/lib/tomcat9/conf/context.xml
2.2.4. 테스트를 위해 Apache Tomcat 서버를 재시작한다.
sudo service tomcat9 restart
2.2.5. 테스트를 위한 jsp 페이지 작성
다음과 같이 /var/lib/tomcat9/webapps/ROOT/jndi.jsp
파일을 작성한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@page import="java.sql.*"%><% Class.forName("kr.xdbc.driver.GenericDriver"); Connection con = DriverManager.getConnection( "xdbc:jdbc:postgresql://localhost/graha|jdbc:postgresql://localhost/graha_backup", "graha", "changeit!" ); con.close(); con = DriverManager.getConnection("xdbc:jdbc:postgresql://localhost/graha", "graha", "changeit!"); con.close(); con = DriverManager.getConnection("xdbc:jdbc:postgresql://localhost/graha_backup", "graha", "changeit!"); con.close(); javax.naming.InitialContext cxt = new javax.naming.InitialContext(); javax.sql.DataSource ds = (javax.sql.DataSource)cxt.lookup("java:/comp/env/jdbc/graha"); con = ds.getConnection(); con.close(); %>
2.3. Realm 설정
Apache Tomcat Realm 설정 을 참고한다.
2.4. Apache Tomcat에서 webapps 외의 디렉토리에 접근하기 위한 설정
파일 업로드 디렉토리를 webapps 외의 다른 디렉토리에 두거나, webapps 디렉토리 혹은 그 하위 디렉토리를 변경하면, 그 디렉토리를 등록해 주어야 한다.
다음과 같이 설정파일을 연다.
sudo systemctl edit --full tomcat9.service
다음과 같이 Apache Tomcat에서 접근하려는 디렉토리를 추가한다.
ReadWritePaths=/data/tomcat/webapps/graha-app-suite/
이 설정이 누락되었다고 해서 항상 에러가 발생하는 것은 아니고, 응용프로그램에 어떠한 변경사항도 없었고, 단지 Apache Tomcat 을 재기동 한 것이 전부인데 갑자기 에러가 발생한다.
다음과 같이 설정을 반영한다.
sudo systemctl daemon-reload
이 설정을 반영하기 위해서는 Apache Tomcat을 재기동해야 한다.
sudo service tomcat9 restart
ReadWritePaths 에 지정한 디렉토리가 존재하지 않는 경우, 다음과 같은 에러메시지와 함께 Apache Tomcat 가 기동되지 않는다.
Job for tomcat9.service failed because the control process exited with error code. See "systemctl status tomcat9.service" and "journalctl -xe" for details.
시키는대로 다음과 같이 실행하면,
systemctl status tomcat9.service
/usr/libexec/tomcat9/tomcat-update-policy.sh
파일을 실행하는 과정에서 에러가 발생했다.
이 경우 ReadWritePaths 부분을 주석으로 막거나, 유효한 디렉토리로 변경하고 나서, 다음의 절차에 따라 다시 Apache Tomcat을 기동해야 한다.
sudo systemctl daemon-reload sudo service tomcat9 restart
2.5. logging 설정
Apache Tomcat 로그(logging.properties) 설정 을 참고한다.
이 설정을 반영하기 위해서는 Apache Tomcat을 재기동해야 한다.
sudo service tomcat9 restart
2.6. ssl 설정
ssl 설정을 위해서는 인증서가 있어야 한다.
도메인의 소유자인 경우 Let's Encrypt 에서 인증서를 발급받을 수 있다.
Let's Encrypt 는 2021년 9월 30일에 중요한 변화가 있었으므로, 오래된 운영체제에서 인증서 오류가 발생할 수 있다.
Firefox 는 에러가 발생하지 않는다.
인증서 오류와 관련해서는 Windows 10 에서 2021년 9월 30일 자 Let's Encrypt 인증서 오류 해결방법 을 참조한다.
2.6.1. 인증서 파일 복사
privkey.pem
, cert.pem
, chain.pem
파일을 /var/lib/tomcat9/conf/letsencrypt/graha.kr/
디렉토리에 복사한다.
graha.kr 은 소유한 도메인 이름으로 변경한다.
privkey.pem
, cert.pem
, chain.pem
파일이 위치한 디렉토리에서 다음과 같은 명령어를 실행한다.
sudo mkdir -p /var/lib/tomcat9/conf/letsencrypt/graha.kr sudo cp privkey.pem /var/lib/tomcat9/conf/letsencrypt/graha.kr/ sudo cp cert.pem /var/lib/tomcat9/conf/letsencrypt/graha.kr/ sudo cp chain.pem /var/lib/tomcat9/conf/letsencrypt/graha.kr/ sudo chown tomcat:tomcat -R /var/lib/tomcat9/conf/letsencrypt
2.6.2. server.xml 파일 변경
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true"> <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" compressibleMimeType= "text/html,text/xml,application/xml,text/plain,text/css,text/javascript,application/javascript" compressionMinSize="2048" /> <SSLHostConfig> <Certificate certificateKeyFile="conf/letsencrypt/graha.kr/privkey.pem" certificateFile="conf/letsencrypt/graha.kr/cert.pem" certificateChainFile="conf/letsencrypt/graha.kr/chain.pem" type="RSA" /> </SSLHostConfig> </Connector>
만약 SNI 을 사용하려면 다음과 같이 해야 한다.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true" defaultSSLHostConfigName="test.graha.kr"> <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" compressibleMimeType= "text/html,text/xml,application/xml,text/plain,text/css,text/javascript,application/javascript" compressionMinSize="2048" /> <SSLHostConfig hostName="test.graha.kr"> <Certificate certificateKeyFile="conf/letsencrypt/graha.kr/privkey.pem" certificateFile="conf/letsencrypt/graha.kr/cert.pem" certificateChainFile="conf/letsencrypt/graha.kr/chain.pem" type="RSA" /> </SSLHostConfig> <SSLHostConfig hostName="test.xdbc.kr"> <Certificate certificateKeyFile="conf/letsencrypt/xdbc.kr/privkey.pem" certificateFile="conf/letsencrypt/xdbc.kr/cert.pem" certificateChainFile="conf/letsencrypt/xdbc.kr/chain.pem" type="RSA" /> </SSLHostConfig> </Connector>
Host 설정도 추가해야 한다.
<Host name="test.graha.kr" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="test.graha.kr_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
test.graha.kr 은 소유한 도메인 이름으로 변경한다.
2.6.3. http 요청을 자동으로 https 요청으로 변경
먼저 디렉토리를 만든다.
sudo mkdir /var/lib/tomcat9/conf/Catalina/test.graha.kr
/var/lib/tomcat9/conf/Catalina/test.graha.kr/rewrite.config
파일을 다음과 같이 작성한다.
RewriteCond %{HTTPS} off RewriteRule ^.*$ https://test.graha.kr%{REQUEST_URI} [L,R]
파일의 소유자를 변경한다.
sudo chown -R tomcat:tomcat /var/lib/tomcat9/conf/Catalina/test.graha.kr
test.graha.kr 은 소유한 도메인 이름으로 변경한다.
2.6.4. 테스트를 위해 Apache Tomcat 서버를 재시작한다.
sudo service tomcat9 restart
2.7. iptable을 이용해서 80 요청을 8080 으로 보내기
2.7.1. 명령어
다음과 같이 80 은 8080에서 443 은 8443 에서 처리하도록 한다.
sudo iptables -A PREROUTING -t nat -i enp0s25 -p tcp --dport 443 -j REDIRECT --to-port 8443 sudo iptables -A PREROUTING -t nat -i enp0s25 -p tcp --dport 80 -j REDIRECT --to-port 8080 sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to-port 8443 sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
다음과 같이 결과를 확인한다.
sudo iptables -t nat -L
2.7.2. 명령어에 대한 간단한 설명
1~2 줄에서 enp0s25 는 eth0, enp3s0 혹은 br0(Network bridge 를 사용하는 경우) 와 같은 것으로 변경해야 하는데, ifconfig -a
혹은 ip a
명령의 결과를 참조하여 변경하면 된다.
3~4 줄은 localhost 내지는 127.0.0.1 를 위한 것이다.
443 포트의 요청(https)은 8443(Apache Tomcat의 default https 포트)으로 이동시키고, 80 요청은 8080 으로 이동시킨다.
http 만 사용하고, localhost 접근이 없다면 첫 번째 줄만 실행하면 된다.
3. 잡담
3.1. Apache Tomcat 을 설치하는 방법에 대해서
이 글에서는 Apache Tomcat 을 ubuntu 의 패키지 시스템으로 설치하는 것을 기준으로 설명했지만, Apache Tomcat 바이너리 파일을 다운로드 받아 압축을 해제하는 방법도 많이 사용된다.
3.1.1. 압축을 해제하는 방법
압축을 해제하는 방법은 다음과 같은 특질이 있다.
- (설치되어 있지 않다면) Java (JDK 혹은 JRE) 를 직접 설치하고, (필요하다면) JAVA_HOME 환경변수를 설정하고, PATH 환경변수도 설정해야 한다.
- 쓸데없는 Context 를 지워야 하고(대부분 모든 Context 를 지워야 한다), logging.properties 에서 해당 항목도 지워야 한다.
- catalina.out 파일 등 로그 파일을 적절히 관리 해야 한다.
- startup.sh 는 정해진 user 로만 실행한다.
3.1.2. (apt get
명령어를 이용해서) 패키지 시스템으로 설치하는 방법
패키지 시스템으로 설치하는 방법의 특질은 다음과 같다.
- Java 를 직접 설치할 필요도 없고, 로그 파일도 시스템이 알아서 관리한다.
- (예를 들어 manager 같이) 쓸데없는 Context 들은 기본으로 설치되지 않고, (그래서 지울 필요도 없고), 필요하다면 추가적으로 설치해야 한다.
- Apache Tomcat에서 webapps 외의 디렉토리에 접근하기 위한 설정(2.4 절)과 같은 숨겨진 복병이 있다.
- ubuntu 의 tomcat 유저는 로그인이 막혀 있는데, 로그인을 풀 것이 아니라면, deploy 하면서 파일을 tomcat 유저로 변경해야 할 것이고, 설정 파일 따위를 편집기로 열 때도 "sudo -u tomcat" 을 붙여야 한다.