Last Updated on 9월 11, 2023 by Jade(정현호)
안녕하세요
이번 포스팅은 우분투 환경에서 Nginx + Tomcat9 연동 및 설정에 관하여 설명 드리려 합니다.
Nginx 설치
Nginx 부터 먼저 설치하도록 하겠습니다.
Nginx 는 Mainline 버전 과 Stable 버전이 있습니다.
새로운 특징, 기능, 버그 패치 등은 Mainline 버전에서 작업하고 그 이후에, 새로운 기능이 추가되지 않고 버그 패치만 하는 게 Stable 버전입니다.
버전 선택에 관련해서 NGINX의 공식 입장은 다음과 같습니다.
We recommend that in general you deploy the NGINX mainline branch at all times.
The main reason to use the stable branch is that you are concerned about possible impacts of new features,
such as incompatibility with third-party modules or the inadvertent introduction of bugs in new features.
기본적으로 Mainline 버전을 택하고 지속적으로 업데이트 하기를 권장하고 있습니다.
Stable 버전은 3rd party(서드 파티) 모듈과 호환성 문제 또는 New Feature 로 인한 문제로 인하여 업데이트가 불가능한 상황에서 사용하면 된다고 합니다.
버전은 사용 환경을 고려하여 선택하시면 될 것 같습니다
포스팅에서는 Mainline 버전으로 하여 최신버전을 설치 하도록 하겠습니다.
* 진행 하는 과정에서의 모든 프롬프트는 ubuntu$ 입니다.
= 필요한 패키지 설치하기
ubuntu$ sudo apt install curl gnupg2 ca-certificates ubuntu-keyring lsb-release -y
## 아래는 둘중 1가지를 선택하여 수행하시면 됩니다.
# mainline 버전의 nginx packages 설치시
ubuntu$ sudo echo "deb http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
or
# stable 버전의 nginx packages 설치시
ubuntu$ echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
패키지의 신뢰성을 확인할 수 있도록 공식 nginx 서명 키를 가져옵니다
ubuntu$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
다운로드한 파일에 적절한 키가 포함되어 있는지 확인합니다.
ubuntu$ gpg --dry-run --quiet \
--no-keyring --import \
--import-options \
import-show /usr/share/keyrings/nginx-archive-keyring.gpg
위의 실행 결과가 아래와 같은지를 확인 합니다.
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 uid nginx signing key <signing-key@nginx.com>
기본 제공 패키지보다 Nginx의 패키지를 선호하도록 리포지토리를 설정 합니다.
ubuntu$ echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
사전 준비가 다 끝났고 이제 nginx 를 설치 합니다.
ubuntu$ sudo apt update
ubuntu$ sudo apt install nginx
ubuntu$ nginx -V
nginx version: nginx/1.19.4
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
built with OpenSSL 1.1.1
필요 패키지 설치
Tomcat 설치전에 필요한 패키지 를 먼저 설치 후 진행하도록 하겠습니다.
# build-essential
sudo apt install build-essential
# libssl-dev , APR-lib
sudo apt install libssl-dev openssl \
libapr1 libapr1-dev
# JDK/JRE 설치
- 8 버전
sudo apt install openjdk-8-jdk openjdk-8-jre
or
- 11 버전
sudo apt install openjdk-11-jdk openjdk-11-jre
or
- 17 버전
sudo apt install openjdk-17-jdk openjdk-17-jre
Java는 원하시는 버전을 선택하여 설치하시면 됩니다
포스팅에서는 8 버전을 사용하였습니다.
Tomcat 설치
ubuntu$ sudo apt install tomcat9 \
tomcat9-admin tomcat9-common \
tomcat9-user libtcnative-1 \
tomcat9-docs tomcat9-examples
* 설치 직후 바로 tomcat 은 기동 됩니다.
Tomcat Native 및 Connector 확인
Tomcat 사용할 수 있는 HTTP Connector는 9.0, 10.0 기준 3개로 기재되어있고 Tomcat Native 미설치시 NIO 로 동작되게 됩니다.
8.0 까지의 문서에서는 아래와 같이 4개로 표기되었습니다.
정리하면 Native Library 를 이용한 APR 방식이 성능에 더 좋다고 알려져 있습니다
그리고 Native Library 미설치시 아래와 같은 warning 메세지도 Tomcat 기동시 마다 확인되게 됩니다
The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path:"
현재 tomcat 설치시 libtcnative-1 패키지도 같이 설치하여 Tomcat Native 는 설치가 된 상태입니다.
ubuntu$ sudo su -
[root]# cd /var/log/tomcat9/
[root]# grep -ai Native catalina*.log
APR based Apache Tomcat Native library [1.2.21] using APR version [1.6.3]
-> 설치된 Tomcat Native 버전은 1.2.21 로 정상적으로 load 된 것으로 로그에서 확인됩니다.
Tomcat Library 가 정상적으로 load 되었음에도 아래처럼 NIO Connector로 구동 되는 경우가 있을 수 있습니다.
이럴 때는 server.xml 에 명시적으로 apr 로 변경해주면 사용할 수 있습니다.
ubuntu$ sudo su -
[root]# cd /var/log/tomcat9/
[root]# grep -ai http catalina*.log
Starting ProtocolHandler ["http-nio-8080"]
server.xml 을 수정합니다.
ubuntu$ cd /etc/tomcat9
ubuntu$ sudo vi server.xml
# original
<Connector port="8080" protocol="HTTP/1.1"
# 아래처럼 protocol 을 수정합니다
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol"
http 를 수정하였다면 tomcat 을 재시작 합니다.
ubuntu$ sudo systemctl restart tomcat9
# 로그 확인
ubuntu$ sudo -i
[root]# cd /var/log/tomcat9/
[root]# grep -ai http catalina*.log
Starting ProtocolHandler ["http-apr-8080"]
--> apr 로 동작 되는 것을 확인할 수 있습니다.
클라우드 보안 정책 및 방화벽 오픈
사용환경에 따라 클라우드 서비스 나 VPS 호스팅 서비스의 보안정책/방화벽에서 포트를 오픈이 필요 할 수 있습니다.
AWS 보안 정책 허용
아래는 AWS의 방화벽(보안 그룹)을 설정 예시입니다.
AWS 콘솔에 접속 후 EC2 로 이동합니다.
인스턴스 메뉴에서 인스턴스 아이디를 선택합니다.
인스턴스 정보 하단에 EC2에 해당하는 보안그룹을 선택합니다.
인바운드 규칙 -> 인바운드 규칙 편집 으로 이동합니다.
유형에서 "HTTP" 를 선택하고 소스에서 "위치무관" 을 선택합니다.
80 포트 HTTP 웹서비스는 모든 곳에서 접속하기에 모든 접속을 허용 으로 설정하게 됩니다.
완료되면 아래와 같이 인바운드 규칙이 설정되게 됩니다.
OS 방화벽 허용
우분투에서는 방화벽을 iptables 로 사용하고 있습니다.
# iptables 간단 설명
먼저 iptables 에 정책이 설정되어 있는지 확인합니다. 설정이 되어 있다면 원하는 포트를 오픈 해야 합니다.
설정이 되어 있지 않다면(사용하지 않으면) 아래 내용은 생략해도 됩니다.
설정된 정책 확인
ubuntu$ sudo iptables -nL
만약 아래와 같이 내용이 출력 된다면 설정된 정책이 없는 것입니다.
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
정책이 설정되어 iptables 를 사용 사용 중 이라면 아래 내용대로 설정을 하시면 됩니다.
iptables 룰 정책 저장을 위한 패키지 설치
ubuntu$ sudo apt-get install iptables-persistent netfilter-persistent
-> 우분투의 iptables 는 재부팅시 내역이 초기화되기 때문에 2개의 패키지를 설치가 필요합니다
특정 포트 오픈 규칙 추가( -I 가장 먼저 추가)
ubuntu$ sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
특정 포트 오픈 규칙 삭제
ubuntu$ sudo iptables -D INPUT -p tcp -m tcp --dport 80 -j ACCEPT
포트 오픈시 특정 IP(123.123.123.123) 로 만 허용
iptables -I INPUT -p tcp -s 123.123.123.123 --dport 80 -j ACCEPT
위의 "포트 오픈시 특정 IP 로 만 허용" 정책 삭제
iptables -D INPUT -p tcp -s 123.123.123.123 --dport 80 -j ACCEPT
정책 영구 저장
ubuntu$ sudo netfilter-persistent save
iptables 정책 설정 후에는 위의 netfilter 를 통해서 save 를 꼭 해야합니다.
Nginx 설정
nginx 의 설정의 홈 디렉토리는 /etc/nginx 입니다.
nginx 최근버전에서는 /snippets /sites-enabled , /sites-available 같은 디렉토리 없이 conf.d 디렉토리만 존재하고 nginx.conf 파일에서는 모든 conf 파일을 include 하여 사용하게 됩니다.
ubuntu$ cd /etc/nginx
ubuntu$ cat nginx.conf | grep conf
include /etc/nginx/conf.d/*.conf
==> /etc/nginx/conf.d/ 아래에 .conf 파일은 자동으로 include 되어 적용되게 됩니다.
먼저 nginx.conf 를 확인해보겠습니다.
ubuntu$ cd /etc/nginx
ubuntu$ sudo vi nginx.conf
user nginx;
<== nginx 에서 사용할 OS로 유저로 nginx 로 사용하면 무난합니다.
#master_process ON; # ON is default
<== 엔진엑스는 하나의 메인 프로세스(마스터 프로세스)와 여러 개의 작업자 프로세스를 시작할 수 있습니다 (ON)
<== ON 이 default 이고 off 로 해제하면 단인 프로세스로 동작하게 됩니다.
<== 해당 옵션은 기재가 되어있지는 않습니다 내용 참고를 위해 기재한 것입니다
worker_processes 4;
or
worker_processes auto;
접속을 받고 처리하는 worker process의 수이며 정한 수만큼 기동시 프로세스가 생성됩니다.
보통 CPU Core 나 CPU Count 와 상관되어 결정되며 설정 이후 CPU의 사용률이 높지 않다면 올려서 사용할 수 있습니다.
혹은 auto 로 nginx 알아서 생성되게 할 수도 있습니다.
저는 일단 4로 설정하고 사용하도록 하겠습니다.
error_log /var/log/nginx/error.log notice;
로그 파일명과 경로, 로깅 레벨을 설정할 수 있습니다.
로깅 레벨은 warn, error crit, alert, and emerg 설정할 수 있습니다.
기동 과 중지 시 로그를 받을 수 있도록 notice 를 기본으로 사용하면 됩니다.
문제 파악이나 설정시 테스트를 위해서는 debug를 사용하면 됩니다.
events {
worker_connections 1024;
}
worker_connections 는 woker 당 가능한 접속 수를 의미합니다.
위에서 worker 4로 지정하였으면 4*1024 하여 4096 Connection이 가능하게 됩니다.
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
log_not_found off;
main 명칭의 로그 포팻으로 설정된 정보가 있고 설정된 main 포맷 Access 로그에서 사용하고 있습니다
log_format main 을 수정하여 사용하거나 별도의 log format을 생성 후 access 로그에서 변경하여 사용할 수 있습니다
### deflate ###
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 500;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_vary on;
gzip_types text/plain text/css text/js text/xml text/javascript application/javascript application/x-javascript application/json application/xml application/rss+xml image/svg+xml image/png;
# gzip 설명
gzip(deflate) 는 HTTP 압축으로 HTTP 데이터는 서버로부터 전송되기 전에 압축됩니다.
nginx.conf 파일에 설정하였기 때문에 모든 server block 에 공통으로 적용되게 됩니다.
gzip on;
이 line을 통해 gzip을 사용할 것이라고 알려주는 것입니다.
gzip_disable "msie6";
IE 6이하에는 적용시키지 않습니다.
gzip_comp_level
압축의 정도를 설정하는 부분으로 높을수록 압축율이 높습니다
그대신 서버에서의 CPU 사용률이 올라가거나 압축에 더 시간이 소요될 수 있어서 적절한 값을 사용하는 것이 좋습니다.
gzip_types
압축을 할 대상 Source 파일의 종류를 지정하는 것입니다.
[참고] 포스팅에서의 -> , => , ==> 는 모두 설명입니다.
이제 각 서버 설정 파일을 수정하도록 하겠습니다
ubuntu$ cd /etc/nginx/conf.d
ubuntu$ sudo cp -rp default.conf default.conf.ori
==> 먼저 default 값으로 설정된 파일은 백업 후 설정을 변경하여 사용하겠습니다.
ubuntu$ sudo vi default.conf
upstream tomcat {
ip_hash;
server 127.0.0.1:8080 max_fails=10 fail_timeout=1s;
keepalive 100;
}
# => Load Balance 와 추가적인 옵션인자를 설정할 수 있는 upstream 구문 절입니다
# => backend 로 연결되는 ip 정보와 접속 실패 관련된 옵션 , backend 와의 keep alive 이 설정되어 있습니다.
server {
listen 80 default_server;
==> 사용할 포트 번호입니다.
==> default_server는 server 절이 여러개 있을 때 IP로 접속하거나 없는 서브도메인 등으로 접속 시 default 로 접속을 하게 되는 sever 절을 의미합니다.
==> server {} 중에서 한곳만 사용할 수 있습니다
server_name localhost;
==> IP나 /etc/hosts에 설정된 호스트네임 , 도메인이 있다면 도메인명을 기재해 줍니다.
==> 도메인이 없다면 localhost 로 지정하시면 됩니다.
# root /usr/share/nginx/html;
root /var/lib/tomcat9/webapps/ROOT;
==> html이나 jsp 파일을 읽을 디렉토리를 지정합니다
==> 기본값은 주석처리 하고 tomcat에 있는 default admin page로 변경하도록 하겠습니다.
index index.jsp index.html index.htm;
==> 접속시 처음 index 할 파일을 지정 합니다 index.jsp 를 추가합니다.
access_log /var/log/nginx/localhost.access.log main;
error_log /var/log/nginx/localhost.error.log;
==> Access , Error 로그는 기본적으로는 주석처리 되어 있습니다.
==> 주석을 해제하고 서버명이나 도메인명 등을 추가하여 로그를 확인할 때 파일명으로 쉽게 찾을 수 있도록 명시적으로 지정하는 것이 좋습니다.
charset utf-8;
==> character set 설정입니다.
# location / 절을 수정합니다.
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
# proxy_pass http://localhost:8080;
proxy_pass http://tomcat; #upstream
# => 위에서 설정한 upstream 명을 기재합니다.
proxy_redirect off;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
* nginx 시작 시 에러가 발생한다면 위의 내용들을 메모장이나 노트패드에 붙여넣은 뒤 다시 복사하여 nginx에 붙여넣어 보시기 바랍니다.
파일을 저장 후 nginx 를 reload 하고 나서 웹페이지 접속을 시도해 봅니다.
ubuntu$ sudo systemctl reload nginx
정상 적이라면 아래와 같은 default 페이지가 표시될 것입니다.
연관된 글
최상위 국가 무료 도메인 발급받기 및 서브 도메인 설정
Nginx 에 Certbot을 통한 무료 SSL인증서 적용 및 HTTP/2 적용
Ubuntu18.04 - LEMP(Linux+Nginx+MariaDB+PHP) 스택 연동 구성
Nginx ModSecurity 설치 및 설정 - Nginx 웹 방화벽
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io
감사합니다
방문해주셔서 감사합니다
좋은 하루되세요
덕분에 설정하는데 많은 도움이 되었습니다. 감사합니다!
안녕하세요
방문과 댓글 감사합니다.
좋은 하루 되세요~
안녕하세요!
개인블로그에 tomcat과 nginx 를 설치해서 도메인 포워딩하는것에 대해 포스팅하고 있는데요,
혹시 괜찮으시다면 nginx 설치부분에 출처는 당연히 남기고 태랑님의 글을 부분 첨부해도 될까요?
내키지 않으신다면 글을 옮기는 것이 아닌 링크만 삽입하는 건 괜찮을까요?ㅎㅎ
안녕하세요
출처 링크만 남겨주시면 편하게 사용하셔도 됩니다.
방문 해주셔서 감사합니다.
좋은 하루 되세요
글 정말 잘 읽었습니다.
선생님처럼 WEB - WAS 구축 및 연동 관련하여 더 Deep 하게 다뤄보고 싶은데 어떻게 공부하면 좋을까요?..
책 혹은 강의가 있다면 추천 부탁드리겠습니다.
안녕하세요
예전에 웹로직 책을 가벼운 마음으로 한번 읽었던 적은 있었는데요 그건 가볍게 읽은것이고요
저도 강의를 듣거나 책을 따로 본적은 없어서요
책을 보신다면 최근의 책으로 평점이 높은걸 보시면 좋을것 같습니다
제가 책이 본 것이 따로 없다보니 추천드리기가 애매한것 같습니다
코멘트 남겨주셔서 감사합니다
좋은 하루 되세요
안녕하세요 글 정말 도움 많이 되었습니다. 제가 nginx 설정 문제로 지금 좀 난항을 겪고 있는데 혹시 도움 주실 수 있으실까요 ㅠ 질문을 okky에 올려놓긴 했는데요.. ㅠ
https://okky.kr/articles/1405418
안녕하세요
금일 업무가 좀 있어서 댓글을 조금 늦게 보았네요
해결은 잘 되셨는지 모르겠습니다.
남겨주신 okky 글은 삭제 되었는지 남겨주신 링크로 들어갔을 때 글이 확인 되지 않네요
진행하시다가 어려운점이 추가로 생기신다면 여기 코멘트로 남겨주세요
감사합니다.
안녕하세요!!
바쁘신 업무중에도 댓글을 달아주셔서 감사합니다.
https://okky.kr/articles/1405573#note-1637496
이 경로도 안보이실까요? 여러 방면으로 해보고 있는데 잘 되질 않아서 안바쁘실때 한번 봐주시면 정말 감사하겠습니다!!! 🙇♂️🙇♂️🙇♂️
안녕하세요
http://localhost:8080 또는
http://localhost:8080/UBIFORM
으로 접속 정상적으로 되는지 체크해봐주세요
네 같은 서버에 있는 express 백엔드 서버에서는 http://localhost:8080/UBIFORM/~~로 통신이 잘 됩니다ㅠ