초보자도 쉽게 따라하는 Linux Tomcat WAR 배포 튜토리얼

사내 레거시 자바 웹 애플리케이션을 새로 세팅한 우분투 서버에 배포하려다 톰캣(Tomcat) 버전과 자바 버전 호환성 문제로 반나절을 날린 적이 있었습니다. WAR 파일만 webapps/에 밀어 넣으면 끝날 줄 알았는데, systemd 서비스 등록부터 권한 설정, 방화벽(UFW), 404 에러까지 줄줄이 터지더군요. 저처럼 사내 서버나 개인 리눅스 인스턴스에 톰캣으로 WAR 배포를 진행하며 삽질하는 분들을 위해 실제 세팅 과정과 트러블슈팅 경험을 정리했습니다.
1. 톰캣 배포 핵심 프로세스
Apache Tomcat은 자바 기반의 웹 애플리케이션을 호스팅하기 위한 대표적인 서블릿 컨테이너입니다. 실제로 서버 환경에서 WAR 파일을 배포할 때는 다음과 같은 파이프라인을 거치게 됩니다:
- 사전 준비: Java 설치 확인, 방화벽 설정, WAR 파일 준비
- Tomcat 설치: 패키지 관리자 사용 vs 바이너리 설치 방법 비교
- 서비스 관리: systemd를 이용한 서비스 등록 및 자동 실행 설정
- WAR 배포: webapps 디렉토리에 WAR 파일 복사 및 자동 배포 확인
- 문제 해결: 404 에러, Java 버전 문제, 보안 정책 조정
- 고급 설정: 모니터링 및 추가 학습 자료 제공
참고: 공식 문서에서는 Tomcat 10.1 다운로드 페이지에서 최신 버전을 확인할 수 있습니다. 또한 Oracle Java 17 설치 가이드를 참고하면 Java 설치에 도움이 됩니다.
2. 사전 준비 사항
2.1 Java 17+ 설치 확인
Tomcat 10.1은 Java 17 이상을 필수로 요구합니다. 다음 명령어로 Java 설치 상태를 확인하세요:
java -version
출력 결과가 17.x.x로 시작하지 않으면 Java 17을 설치해야 합니다. Ubuntu에서는 다음 명령어로 설치할 수 있습니다:
sudo apt update
sudo apt install openjdk-17-jdk -y
CentOS에서는:
sudo yum install java-17-openjdk-devel -y
설치 후 JAVA_HOME 환경 변수를 설정해야 합니다. Ubuntu/CentOS 공통 설정 방법:
echo 'export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:/bin/java::")' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
2.2 방화벽 설정
Tomcat 기본 포트는 8080입니다. SSH(22)와 Tomcat(8080) 포트를 열어주세요:
-
Ubuntu:
sudo ufw allow 22/tcp sudo ufw allow 8080/tcp -
CentOS:
sudo firewall-cmd --permanent --add-port=22/tcp sudo firewall-cmd --permanent --add-port=8080/tcp sudo firewall-cmd --reload
2.3 WAR 파일 준비
샘플 WAR 파일이 없다면 Spring Boot 프로젝트를 생성해 테스트용 WAR를 만들 수 있습니다. 다음 pom.xml을 사용하세요:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
그리고 간단한 컨트롤러 클래스를 작성하세요:
package com.example.demo;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
@RestController
public class HelloController extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(HelloController.class);
}
@GetMapping("/")
public String home() {
return "Hello from Tomcat!";
}
}
Maven으로 WAR를 빌드하려면:
mvn clean package
생성된 WAR 파일은 target/demo-0.0.1-SNAPSHOT.war에 위치합니다.
3. 단계별 설치 및 배포
3.1 Tomcat 설치 방법 비교
Tomcat 설치에는 두 가지 주요 방법이 있습니다:
-
패키지 관리자 사용 (apt/yum)
- 장점: 시스템 통합이 용이
- 단점: 최신 버전 지원이 느림
- Ubuntu:
sudo apt install tomcat10 -y - CentOS:
sudo yum install tomcat -y
-
바이너리 설치 (권장)
- 장점: 최신 버전 설치 가능
- 단점: 수동 설정 필요
- 공식 사이트에서 압축 해제:
cd /opt sudo wget https://downloads.apache.org/tomcat/tomcat-10/v10.1.12/bin/apache-tomcat-10.1.12.tar.gz sudo tar -xzvf apache-tomcat-10.1.12.tar.gz sudo ln -s apache-tomcat-10.1.12 tomcat
팁: 프로덕션 환경에서는 바이너리 설치가 권장됩니다. 패키지 관리자는 때로는 오래된 버전을 포함할 수 있기 때문입니다.
3.2 systemd 서비스 등록
Tomcat을 백그라운드 서비스로 실행하려면 systemd를 설정해야 합니다. /etc/systemd/system/tomcat.service 파일을 생성하세요:
[Unit]
Description=Apache Tomcat 10 Web Application Container
After=network.target
[Service]
Type=forking
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='JAVA_HOME=/usr/lib/jvm/java-17-openjdk'
Environment='JAVA_OPTS=-Djava.security.egd=file:/dev/./urandom -Djava.awt.headless=true'
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
ExecReload=/opt/tomcat/bin/shutdown.sh ; /opt/tomcat/bin/startup.sh
User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
서비스 활성화 및 시작:
sudo systemctl daemon-reload
sudo systemctl enable tomcat
sudo systemctl start tomcat
3.3 WAR 파일 배포
WAR 파일은 Tomcat의 webapps 디렉토리에 복사하면 자동으로 배포됩니다:
cp demo-0.0.1-SNAPSHOT.war /opt/tomcat/webapps/
배포 상태를 확인하려면 로그 파일을 확인하세요:
cat /opt/tomcat/logs/catalina.out
브라우저에서 http://[서버IP]:8080/demo로 접속하여 “Hello from Tomcat!” 메시지가 표시되는지 확인하세요.
4. 트러블슈팅
4.1 404 에러 해결
WAR 파일이 배포되었지만 404 에러가 발생한다면 다음을 확인하세요:
-
로그 확인:
tail -f /opt/tomcat/logs/catalina.out에러 메시지가 있는지 확인합니다.
-
컨텍스트 패스 확인: WAR 파일 이름이
demo.war라면 접근 주소는http://[서버IP]:8080/demo입니다. -
서버 재시작:
sudo systemctl restart tomcat
4.2 Java 버전 불일치 문제
Tomcat 10.1은 Java 8 이상을 지원하지만, 최신 기능을 사용하려면 Java 17이 필요합니다. 다음 명령어로 사용 중인 Java 버전을 확인하세요:
/opt/tomcat/bin/version.sh
만약 잘못된 Java 버전이 사용된다면 CATALINA_OPTS에 Java 경로를 명시적으로 지정하세요:
export CATALINA_OPTS="$CATALINA_OPTS -Djava.home=/usr/lib/jvm/java-17-openjdk"
4.3 SELinux/AppArmor 보안 정책
SELinux나 AppArmor가 활성화된 환경에서는 Tomcat이 파일에 접근하지 못할 수 있습니다. Ubuntu에서는 AppArmor를 일시적으로 비활성화해 테스트할 수 있습니다:
sudo systemctl stop apparmor
CentOS에서 SELinux 모드 확인:
getenforce
SELinux를 일시적으로 Permissive 모드로 전환:
sudo setenforce 0
영구적으로 비활성화하려면 /etc/selinux/config 파일을 편집하세요:
SELINUX=disabled
5. 마치며
이 튜토리얼에서는 Linux 서버에 Tomcat을 설치하고 WAR 파일을 배포하는 전체 과정을 다뤘습니다. 핵심 내용을 요약하면 다음과 같습니다:
- Tomcat 10.1 설치에는 바이너리 방식이 최신 버전 사용에 유리합니다.
- WAR 파일은 webapps 디렉토리에 복사만으로 자동 배포됩니다.
- 트러블슈팅 시 로그 파일과 보안 정책을 반드시 확인해야 합니다.
추가로 학습할 자료:
모니터링 시스템 구축을 원한다면 JMXTrans와 Grafana를 연동하는 방법을 고려해보세요. 이는 서버 리소스 사용량과 애플리케이션 성능을 실시간으로 모니터링할 수 있게 해줍니다.