안녕하세요. 비전 IDC 기술팀입니다.
JSP나 Java 서블릿 기반 웹 애플리케이션을 운영하려면 Java 실행 환경과 서블릿 컨테이너인 Tomcat이 필요합니다. 또한 외부 요청은 80/443 포트의 Apache가 받고, Apache가 내부의 Tomcat으로 요청을 전달하는 구성이 많이 사용됩니다.
이 문서에서는 CentOS 7 기본 저장소의 패키지를 사용해 OpenJDK와 Tomcat을 설치하고, JAVA_HOME 확인, Tomcat 서비스 시작과 8080 포트 테스트, firewalld 설정을 거쳐 Apache의 mod_proxy_http로 리버스 프록시를 구성하는 방법을 설명합니다. 소스 컴파일이 필요한 mod_jk 대신 Apache 기본 모듈만 사용하므로 유지보수가 간단합니다.
적용 환경
- 운영체제: CentOS Linux 7
- Java: OpenJDK 8 (
java-1.8.0-openjdk-devel), 필요 시 OpenJDK 11 (java-11-openjdk-devel) - Tomcat: CentOS 7 기본 저장소의
tomcat패키지 (Tomcat 7 계열), 서비스명tomcat - 웹 서버: Apache HTTP Server 2.4 (
httpd), 연동 모듈mod_proxy/mod_proxy_http - 예시 도메인:
app.example.com
1. OpenJDK 설치
먼저 서버에 Java가 이미 설치되어 있는지 확인합니다.
java -version
rpm -qa | grep -i openjdk
설치되어 있지 않다면 OpenJDK를 설치합니다. -devel 패키지에는 실행 환경(JRE)과 함께 컴파일러 javac 등 개발 도구가 포함됩니다. CentOS 7 저장소의 Tomcat 7 패키지와 함께 사용할 때는 OpenJDK 8을 기준으로 하는 것이 무난합니다.
sudo yum install -y java-1.8.0-openjdk-devel
애플리케이션이 Java 11을 요구한다면 다음 패키지를 설치할 수 있습니다. 두 버전을 함께 설치해도 되지만, 이 경우 기본으로 사용할 버전을 반드시 확인해야 합니다.
sudo yum install -y java-11-openjdk-devel
설치 후 버전을 확인합니다.
java -version
javac -version
여러 버전이 설치되어 있다면 alternatives로 기본 java와 javac를 선택합니다. 번호를 입력해 원하는 버전을 지정합니다.
sudo alternatives --config java
sudo alternatives --config javac
간단한 컴파일 테스트
Java 개발 도구가 정상인지 간단한 파일로 확인할 수 있습니다.
mkdir -p ~/javatest && cd ~/javatest
cat > Hello.java <<'EOF'
public class Hello {
public static void main(String[] args) {
System.out.println("Java is working");
}
}
EOF
javac Hello.java
java Hello
Java is working이 출력되면 정상입니다.
2. JAVA_HOME 경로 확인 및 설정
일부 빌드 도구나 애플리케이션은 JAVA_HOME 환경 변수를 필요로 합니다. 먼저 현재 사용 중인 javac의 실제 경로를 확인합니다.
readlink -f "$(which javac)"
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx.x86_64/bin/javac 형태로 출력되며, 끝의 /bin/javac를 제외한 경로가 JDK 설치 위치입니다. 다만 이 경로에는 세부 버전 번호가 포함되어 있어 yum update로 OpenJDK가 갱신되면 바뀝니다. 그래서 JAVA_HOME에는 alternatives가 관리하는 고정 경로를 사용하는 것이 좋습니다.
ls -l /usr/lib/jvm/
목록에서 java-1.8.0-openjdk(OpenJDK 11은 java-11-openjdk)처럼 세부 버전이 없는 심볼릭 링크를 확인한 뒤, 전체 사용자에게 적용되도록 /etc/profile.d/에 파일을 만듭니다.
sudo tee /etc/profile.d/java.sh > /dev/null <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export PATH=$JAVA_HOME/bin:$PATH
EOF
source /etc/profile.d/java.sh
echo $JAVA_HOME
"$JAVA_HOME/bin/javac" -version
3. Tomcat 설치 및 서비스 시작
CentOS 7 기본 저장소에서 Tomcat을 설치합니다. tomcat-webapps는 기본 ROOT 페이지와 예제를, tomcat-admin-webapps는 관리자 화면(Manager)을 제공합니다. 운영 서버에서 관리자 화면을 사용하지 않는다면 tomcat-admin-webapps는 설치하지 않아도 됩니다.
sudo yum install -y tomcat tomcat-webapps
rpm -q tomcat
패키지로 설치한 Tomcat의 주요 경로는 다음과 같습니다.
| 구분 | 경로 |
|---|---|
| 서비스 환경 설정 | /etc/tomcat/tomcat.conf |
| 서버 설정(커넥터, 포트) | /etc/tomcat/server.xml |
| 웹 애플리케이션 배포 위치 | /var/lib/tomcat/webapps/ |
| 로그 | /var/log/tomcat/ |
| 실행 계정 | tomcat |
Tomcat 서비스가 사용할 Java 경로를 확인합니다. 필요하면 JAVA_HOME 값을 앞 장에서 확인한 경로로 수정합니다.
grep -n JAVA_HOME /etc/tomcat/tomcat.conf
sudo vi /etc/tomcat/tomcat.conf
JAVA_HOME="/usr/lib/jvm/jre-1.8.0-openjdk"
위 값은 예시입니다. ls -l /usr/lib/jvm/로 실제 존재하는 경로를 확인한 뒤 지정하십시오. JDK 경로(java-1.8.0-openjdk)와 JRE 경로(jre-1.8.0-openjdk) 모두 Tomcat 실행에 사용할 수 있습니다.
Tomcat을 시작하고 부팅 시 자동 실행되도록 설정합니다.
sudo systemctl enable --now tomcat
systemctl status tomcat
Tomcat이 8080 포트에서 대기하는지 확인합니다. 시작 직후에는 초기화에 몇 초에서 수십 초가 걸릴 수 있습니다.
sudo ss -tlnp | grep java
4. 8080 포트로 동작 테스트
서버 내부에서 먼저 응답을 확인합니다. HTTP 상태 코드 200이 표시되면 정상입니다.
curl -I http://127.0.0.1:8080/
간단한 JSP 테스트 페이지를 만들어 JSP 처리가 되는지도 확인합니다. 새 디렉터리를 webapps 아래에 만들면 Tomcat이 자동으로 애플리케이션으로 인식합니다.
sudo mkdir -p /var/lib/tomcat/webapps/hello
sudo tee /var/lib/tomcat/webapps/hello/index.jsp > /dev/null <<'EOF'
<%@ page contentType="text/html; charset=UTF-8" %>
<html><body>
<p>Tomcat JSP test: <%= new java.util.Date() %></p>
<p>Java version: <%= System.getProperty("java.version") %></p>
</body></html>
EOF
sudo chown -R tomcat:tomcat /var/lib/tomcat/webapps/hello
curl http://127.0.0.1:8080/hello/
현재 시각과 Java 버전이 출력되면 Tomcat과 JSP 처리가 정상입니다.
외부에서 8080 포트 테스트 (선택)
브라우저에서 직접 확인하고 싶다면 firewalld에서 8080 포트를 임시로 허용합니다. --permanent 없이 추가한 규칙은 firewalld를 다시 읽거나 재시작하면 사라집니다.
sudo firewall-cmd --add-port=8080/tcp
브라우저에서 http://서버IP:8080/hello/로 접속해 확인한 뒤, Apache 연동을 진행하기 전에 규칙을 제거합니다.
sudo firewall-cmd --remove-port=8080/tcp
5. Apache 설치와 mod_proxy_http 리버스 프록시 구성
Apache를 설치하고 프록시 모듈이 로드되어 있는지 확인합니다. CentOS 7의 httpd 패키지는 /etc/httpd/conf.modules.d/00-proxy.conf에서 mod_proxy와 mod_proxy_http를 기본으로 로드합니다.
sudo yum install -y httpd
httpd -M 2>/dev/null | grep -E 'proxy_module|proxy_http_module'
proxy_module과 proxy_http_module이 모두 표시되면 추가 설치 없이 사용할 수 있습니다. 가상 호스트 설정 파일을 만듭니다.
sudo vi /etc/httpd/conf.d/app.example.com.conf
아래는 도메인으로 들어온 모든 요청을 로컬 Tomcat(8080)으로 전달하는 예시입니다.
<VirtualHost *:80>
ServerName app.example.com
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ErrorLog logs/app.example.com-error_log
CustomLog logs/app.example.com-access_log combined
</VirtualHost>
ProxyRequests Off: 서버가 임의의 외부 주소로 요청을 중계하는 포워드 프록시로 악용되지 않도록 합니다. 리버스 프록시에는 필요하지 않으므로 반드시 Off로 둡니다.ProxyPreserveHost On: 브라우저가 보낸 Host 헤더를 Tomcat에 그대로 전달합니다.ProxyPass/ProxyPassReverse: 요청 경로를 Tomcat 주소로 전달하고, Tomcat이 보내는 리다이렉트 응답의 주소를 다시 Apache 주소로 바꿉니다.
특정 경로만 Tomcat으로 보내고 나머지는 Apache가 직접 처리하려면 경로를 지정합니다.
ProxyPass /hello/ http://127.0.0.1:8080/hello/
ProxyPassReverse /hello/ http://127.0.0.1:8080/hello/
설정 문법을 확인한 뒤 Apache를 시작합니다.
sudo apachectl configtest
sudo systemctl enable --now httpd
이미 실행 중이었다면 설정을 다시 읽어 들입니다.
sudo systemctl reload httpd
6. SELinux와 firewalld 설정
SELinux에서 Apache의 백엔드 연결 허용
SELinux가 Enforcing 상태라면 Apache가 8080 포트로 연결하는 동작이 차단되어 503 Service Unavailable이 표시될 수 있습니다. 먼저 상태를 확인합니다.
getenforce
getsebool httpd_can_network_connect
Apache 에러 로그에 Permission denied와 함께 백엔드 연결 실패가 기록되어 있다면 다음 명령으로 Apache의 네트워크 연결을 허용합니다. -P 옵션은 재부팅 후에도 설정을 유지합니다.
sudo setsebool -P httpd_can_network_connect 1
firewalld에서 웹 포트 허용
외부 사용자는 Apache의 80(HTTPS 사용 시 443) 포트로만 접속하도록 허용합니다. Tomcat 8080 포트는 외부에 열지 않습니다.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
브라우저에서 http://app.example.com/hello/로 접속해 JSP 테스트 페이지가 표시되면 연동이 완료된 것입니다. DNS가 아직 연결되지 않았다면 서버에서 다음과 같이 Host 헤더를 지정해 확인할 수 있습니다.
curl -H 'Host: app.example.com' http://127.0.0.1/hello/
7. Tomcat 보안 설정 정리 (AJP 커넥터, 8080 바인딩)
사용하지 않는 AJP 커넥터 비활성화
이 문서의 구성은 HTTP 프록시만 사용하므로 AJP 커넥터(기본 8009 포트)는 필요하지 않습니다. 현재 AJP 커넥터가 활성화되어 있는지 확인합니다.
grep -n 'protocol="AJP' /etc/tomcat/server.xml
sudo ss -tlnp | grep 8009
활성화되어 있다면 server.xml을 백업한 뒤 해당 <Connector ... protocol="AJP/1.3" ... /> 요소를 XML 주석(<!-- -->)으로 감싸 비활성화합니다.
sudo cp -a /etc/tomcat/server.xml /root/server.xml.backup
sudo vi /etc/tomcat/server.xml
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
Tomcat HTTP 커넥터를 로컬로 제한
Apache를 통해서만 접속하도록 하려면 8080 커넥터에 address 속성을 추가해 로컬에서만 대기하도록 할 수 있습니다.
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"
redirectPort="8443" />
변경 후 Tomcat을 재시작하고 대기 주소를 확인합니다. 127.0.0.1:8080으로 표시되면 외부에서 8080으로 직접 접속할 수 없습니다.
sudo systemctl restart tomcat
sudo ss -tlnp | grep 8080
8. 자주 발생하는 문제와 확인 방법
| 증상 | 가능한 원인 | 확인 및 해결 방향 |
|---|---|---|
systemctl start tomcat 후 곧바로 중지됨 |
JAVA_HOME 경로 오류 또는 Java 미설치 |
journalctl -u tomcat -n 50으로 로그를 확인하고 /etc/tomcat/tomcat.conf의 경로가 실제 존재하는지 확인합니다. |
| 8080 포트가 열리지 않음 | 다른 프로세스가 8080 사용 중 또는 server.xml 오류 | ss -tlnp | grep 8080으로 점유 프로세스를 확인하고 /var/log/tomcat/의 catalina 로그를 확인합니다. |
Apache 접속 시 503 Service Unavailable |
Tomcat 중지 또는 SELinux 차단 | curl -I http://127.0.0.1:8080/로 Tomcat 응답을 확인하고, 응답이 정상이면 httpd_can_network_connect 값을 확인합니다. |
| Apache 기본 테스트 페이지만 표시됨 | ServerName 불일치 또는 설정 파일 미적용 |
apachectl -S로 가상 호스트 목록을 확인하고 접속 도메인과 ServerName이 같은지 확인합니다. |
로그인 후 주소가 127.0.0.1:8080으로 바뀜 |
ProxyPassReverse 누락 |
ProxyPass와 같은 경로로 ProxyPassReverse를 추가합니다. |
| JSP 수정 내용이 반영되지 않음 | 브라우저 캐시 또는 배포 경로 오류 | 실제 배포 경로가 /var/lib/tomcat/webapps/인지 확인하고, 필요 시 Tomcat을 재시작합니다. |
주요 로그는 다음 명령으로 확인합니다.
sudo journalctl -u tomcat -n 100 --no-pager
sudo ls -lt /var/log/tomcat/
sudo tail -n 50 /var/log/httpd/app.example.com-error_log
해결되지 않으면 비전 IDC 1:1 문의(https://visionidc.com/submitticket.php) 또는 텔레그램 VISIONIDC24로 문의해 주시기 바랍니다.
9. 관련 기술자료와 공식 참고자료
관련 비전 IDC 기술자료
- CentOS 7에서 yum 저장소 오류를 Vault 저장소로 변경하여 해결하는 방법 — 패키지 설치 단계에서 저장소 오류가 발생할 때
- CentOS 버전 확인 방법 — 작업 전 운영체제 버전 확인
- Ubuntu 22.04에서 메모리 사용량이 높은 프로세스를 확인하는 방법 — Java 프로세스 메모리 사용량 점검 시 참고
- CentOS 7에서 No space left on device 오류가 발생할 때 원인을 확인하는 방법 — 로그 증가로 디스크가 가득 찼을 때
공식 참고자료
- Apache Tomcat 7 Configuration Reference - The AJP Connector — AJP 커넥터 속성
- Apache HTTP Server 2.4 - mod_proxy —
ProxyPass,ProxyPassReverse,ProxyPreserveHost - Apache HTTP Server 2.4 - mod_proxy_http
- CentOS Project - CentOS Linux — CentOS Linux 7 지원 종료 일정
10. 자주 묻는 질문
mod_jk와 mod_proxy_http 중 무엇을 사용해야 하나요?
새로 구성한다면 Apache에 기본 포함된 mod_proxy_http를 권장합니다. 별도 소스 컴파일이나 모듈 업데이트 관리가 필요 없고, HTTP 프로토콜을 그대로 사용하므로 문제를 확인하기도 쉽습니다. 기존에 mod_jk로 운영 중인 서버는 동작을 충분히 테스트한 뒤 전환하십시오.
yum으로 Tomcat 8이나 9를 설치할 수 있나요?
CentOS 7 기본 저장소에서 제공하는 tomcat 패키지는 Tomcat 7 계열입니다. 더 높은 버전이 필요하다면 Apache Tomcat 공식 배포판을 수동으로 설치해야 하며, 이 경우 서비스 등록과 보안 업데이트도 직접 관리해야 합니다. 신규 구축이라면 최신 Tomcat을 지원하는 운영체제로 구성하는 편이 장기적으로 유리합니다.
HTTPS는 어떻게 적용하나요?
Apache에서 SSL을 처리하고 Tomcat으로는 내부 HTTP로 전달하는 구성이 일반적입니다. mod_ssl을 설치하고 443 가상 호스트에 인증서와 함께 동일한 ProxyPass 설정을 추가하면 됩니다. Tomcat에는 별도 인증서를 설정하지 않아도 됩니다.
Tomcat이 사용하는 메모리 크기를 조정할 수 있나요?
/etc/tomcat/tomcat.conf의 JAVA_OPTS 항목에 -Xms, -Xmx 값을 지정해 조정할 수 있습니다. 서버 전체 메모리와 다른 서비스 사용량을 고려해 설정한 뒤 Tomcat을 재시작하십시오.
마무리
이번 문서에서는 CentOS 7 기본 저장소 패키지로 OpenJDK와 Tomcat을 설치하고, JAVA_HOME을 고정 경로로 지정한 뒤 Apache의 mod_proxy_http로 Tomcat과 연동하는 방법을 살펴봤습니다. 연동 후에는 Tomcat의 8080 포트와 사용하지 않는 AJP 커넥터를 외부에 노출하지 않도록 정리하는 것이 중요합니다.
CentOS 7과 Tomcat 7은 모두 지원이 종료된 버전이므로, 기존 서비스를 유지하는 동안에도 보안 설정을 최소한으로 점검하고 지원 중인 운영체제와 Tomcat 버전으로의 이전 계획을 함께 검토하시기 바랍니다.
