Spring Boot 배포하기 (Nginx, HTTPS 설정) 2

김기현·2022년 12월 27일
3
post-thumbnail

개발환경

  • Java11, Gradle
  • AWS EC2, Route 53, AWS Certificate Manager
  • OS : EC2 Ubuntu 20.04 LTS
    LTS를 사용하자
  • EC2 보안그룹EC2 보안그룹 인바운드 규칙은 사진과 같다.

EC2>보안그룹>인바운드 규칙에서 필요한 포트를 먼저 열어놔도 상관없다.
레마 피드백 : SSH는 반드시 내 IP만 허용!
SSH 뿐만 아니라 소스를 저렇게 다 열어두지 않습니다. 보안상 위험하다만 편의상 다음과 같이 진행하려 합니다.

1. SSH로 EC2 접근

EC2 환경을 만들 때 생성했던 .pem을 다운받고, 키가 있는 위치에서 ssh -i 키이름 [ubuntu@](mailto:ubuntu@43.200.111.101)퍼블릭 IPv4 주소 를 입력하자

예시 : ssh -i week3_umc.pem [ubuntu@43.200.111.101](mailto:ubuntu@43.200.111.101)
그러면 다음의 에러가 나온다.

아래의 예시처럼 private_key의 퍼미션을 한정하자

chmod 400 week3_umc.pem
아래의 사진처럼 우분투 서버에 들어와진다.

2. Java를 설치

sudo apt install openjdk-11-jre-headless

3. EC2 서버에 GIT 클론

스프링 부트 프로젝트를 다운받자. 단순히 아래처럼 원하는 주소로 git clone하면 된다.

git clone [https://github.com/PCL-Spring/YHIM.git](https://github.com/PCL-Spring/YHIM.git)

4. Spring Boot 프로젝트 Build

그리고 아래의 명령어로 spring boot 프로젝트 배포를 위해 build를 하자
sudo ./gradlew build

만약 test코드 때문에 에러가 난다면 gradle build -x test 처럼 옵션을 주자

현업에서는 서버를 띄울 때 테스트코드를 무시한다.

그러면 build/libs 경로에 jar파일이 생성된 것을 확인할 수 있다.

java -jar 파일이름.jar 을 입력해 프로젝트를 실행하자

(실행할 때 plane이 붙어있는 스냅샷은 안열린다. 조심하자)

서버가 실행되고 퍼블릭 IPv4 주소:포트번호 를 입력하면 로컬에서 실행한 환경처럼 잘 실행이 된다.

퍼블릭 프라이빗 IPv4 주소를 헷갈리지 말자!

5. Nginx 설치

  • Reverse Proxy / Nginx VS Apache /Nginx Command 기본 Nginx 설정 파일을 보면 Forward(순방향) Proxy임을 확인할 수 있습니다. Forward Proxy는 경로로 들어오는 경우, root에 지정된 경로에 따라 일치하는 파일로 이동하여 웹에서 내용을 보여줍니다. 하지만 Nginx 서버에서 Reverse Proxy 기능도 제공합니다.

    Reverse Proxy

    Reverse Proxy는 Forward Proxy와는 다르게 외부에서 내부 서버가 제공하는 서비스를 접근할 때, proxy 서버를 먼저 거쳐 내부 서버로 들어오는 방식입니다. 그리고 외부 클라이언트는 실제 내부 서버의 존재를 모릅니다. 그리고 모든 접속은 Reverse Proxy서버에게 들어오며, Reverse Proxy 서버는 요청에 맵핑되는 서버의 정보에게 요청을 넘깁니다. 이로써 내부 서버의 정보를 외부로부터 감추루 수 있기 떄문에 보안이 높아집니다. 또 proxy 서버가 내부 서버의 정보를 알고 있으므로 로드밸런싱을 통해 부하 여부에 따라 요청을 분배할 수 있습니다. Proxy 서버를 사용하여 캐싱 기능과 트래칙 분산 기능을 결합시켜 전반적인 서버 성능의 향상 또한 기대할 수 있습니다. 참고로 Nginx는 서버가 부팅될 때 자동으로 시작됩니다.

    Nginx VS Apache

    Apache는 프로세스를 fork하거나 쓰레드를 사용하지만,Nginx는 CPU와 관계없이 IO들을 전부 Event Listener로 미루기 때문에 흐름이 끊기지 않고 응답이 빠른 작업이 가능합니다. 추가적으로 Nginx는 Apache와 달리 동시접속자 수가 많아져도 추가적인 생성비용이 들지 않고, 메모리적인 측면에서 Nginx가 System Resource를 적게 처리한다는 장점이 있습니다.

    Nginx Command

    nginx -tnginx 설정 파일의 문법이 올바른지 확인 sudo service nginx statusnginx 상태 확인 sudo service nginx start nginx 실행 sudo service nginx restart중지 후 재실행 sudo servcie nginx reload수정된 파일 적용하여 연결을 끊지 않고 재실행 sudo service nginx stopnginx 중지 sudo service disable nginx자동 시작 비활성화 sudo service enable nginx자동 시작 활성화

웹서버 nginx를 설치하고 상태를 확인하자

sudo apt-get update 맨처음 서버를 열고 install하기 전에 update를 하자

sudo apt install nginx -y nginx 설치

nginx -v nginx 버전 확인

sudo service nginx status nginx 상태 확인

중간에 초록 글씨로 active(running)이 있다면 잘 실행되고 있는 것이다.

그렇지 않다면 sudo service nginx start 로 nginx를 실행하자

다시 java -jar 파일이름.jar 을 입력해 프로젝트를 실행하면 Nginx 기본 페이지가 출력된다.

항상 프로젝트를 띄울 때는 build/libs 경로에서 java -jar 파일이름.jar 구문을 입력하거나, java -jar build/libs/파일이름.jar 처럼 경로를 입력하고 띄우자. 아니면 스냅샷을 찾지 못하니 조심.

개발자 도구를 열어 원격 주소의 포트가 80임를 확인하자

만약 80포트가 아니라면 nginx를 삭제하고 다시 설치한 후 이 과정을 반복하자. 뭔가 잘 안될 때는 해당 기능을 과감히 삭제하고 다시 설치하면 삽질을 줄일 수 있다.

6. Nginx server block 설정 및 서버 연동

  • 파일 디렉토리 등 세부 내용 설명 Nginx 웹 서버를 사용할 때 서버블록을 사용해 구성 세부 정보를 캡슐화하고 단일 서버에서 둘 이상의 도메인을 호스팅할 수 있습니다. 단일 사이트를 호스팅하는 경우 기본적으로 활성화된 서버 블록인 /var/www/html을 활용하면 되지만, 여러 사이트를 호스팅할 경우 /var/www/{domain}/html과 같은 방식으로 디렉토리 구조를 수정해 적용할 수 있습니다. Nginx 파일 및 디렉토리
    • 콘텐츠

      /var/www/html : 기본적으로 기본 Nginx 페이지가 있습니다. Nginx 구성 파일을 변경 수 있습니다.

    • 서버 구성

      /etc/nginx/nginx.conf기본 Nginx 구성 파일입니다. Nginx 전역 구성을 변경하도록 수정할 수 있습니다.

      /etc/nginx/sites-available/사이트별로 서버 블록을 저장할 수 있는 디렉토리입니다. Nginx는 sites-enabled 디렉토리에 연결되지 않은 경우 이 디렉토리의 구성 파일을 사용하지 않습니다. 일반적으로 sites-available 디렉토리에서 서버 블록이 구성된 후에 다른 디렉토리에 연결되어 사용할 수 있게 됩니다.

      /etc/nginx/sites-enabled활성화된 사이트별 서버 블록이 저장되는 디렉토리입니다. 일반적으로 sites-available 디렉토리에 있는 구성파일에 연결해 생성됩니다.

    • 서버 로그

      /var/log/nginx/access.log별도로 구성되지 않는 한 웹 서버에 대한 모든 요청이 기록됩니다.

      /var/log/nginx/error.log모든 Nignx 오류가 기록됩니다.

Proxy를 설정하자

sudo mkdir /var/log/nginx/proxy/ log, error 파일이 들어갈 디렉토리 생성

sudo vi /etc/nginx/proxy_params

이 명령어를 입력하면 수정 창이 나온다. 코드를 이렇게 작성해주자. 코드는 아래 토글에 있다.

  • 코드
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-NginX-Proxy true;
    
    client_max_body_size 256M;
    client_body_buffer_size 1m;
    
    proxy_buffering on;
    proxy_buffers 256 16k;
    proxy_buffer_size 128k;
    proxy_busy_buffers_size 256k;
    
    proxy_temp_file_write_size 256k;
    proxy_max_temp_file_size 1024m;
    
    proxy_connect_timeout 300;
    proxy_send_timeout 300;
    proxy_read_timeout 300;
    proxy_intercept_errors on;

시간이 된다면 버퍼사이즈, 타임아웃 등 한번 찾아보자

7. 도메인 가져오기

가비아, freenom 등 도메인 판매처에서 도메인을 선정하자.

AWS Route 53으로 도메인 등록

도메인을 구매했다면 AWS Route 53에 등록하자.

호스팅 영역을 생성하면(도메인 이름 입력란에는 내가 구매한 도메인을 입력, 퍼블릭 호스팅 영역으로 생성) 다음의 사진처럼 레코드를 생성할 수 있는 창이 나온다.

주황색 레코드를 생성하자. 레코드 유형A를, 에는 꼭꼭꼭 퍼블릭 IPv4 주소를 넣자! 프라이빗 IPv4 주소가 아니다.

그러면 3가지 레코드가 있는 것을 확인할 수 있다.

8. 도메인 네임서버 변경

네임 서버를 변경해야 한다.

유형이 NS인 레코드를 선택하시면 총 4개의 값/트래픽 라우팅 대상이 들어가 있는 것을 확인할 수가 있다

아래와 같이 네임서버들을 가비아에 있는 구매한 도메인의 네임서버로 바꿔주자

(레코드에 값/트래픽 라우팅 대상을 자세히 보면 . 으로 끝나는데, 가비아에서는 마지막 온점을 없애주자)

이제 도메인을 연결해서 사용할 수 있다.

9. 서버 블록 생성

아래 사진처럼 도메인과 jar 파일을 이용하기 위해서 기본 구성 파일을 수정해 서버 블록을 생성하자

sudo vi /etc/nginx/sites-available/{domain}

예시 : sudo vi /etc/nginx/sites-available/springworld.site

sudo vi /etc/nginx/sites-available/naver.com

그러면 편집화면이 나타난다. 아래의 코드를 입력해주자

server { # server 블록
	listen 80;

    server_name {domain} www.{domain};

    access_log /var/log/nginx/proxy/access.log;
    error_log /var/log/nginx/proxy/error.log;

    location / { # location 블록
        include /etc/nginx/proxy_params;
        proxy_pass http://{퍼블릭IP주소}:포트번호;	# reverse proxy의 기능
    }
}

  • 해당 코드 설명 이 코드를 추가하면서 location 블록의 proxy_pass
    를 통해 8088번 포트를 통해 접속해야 볼 수 있는 화면(Spring Boot 프로젝트 화면)을 80번(HTTP) 포트에 접속했을 때 확인할 수 있도록 설정, 즉 Reverse proxy
    의 기능을 하게 할 수 있습니다.

옵션을 조정하자

sudo vi /etc/nginx/nginx.conf

http { 
	...
	server_names hash_bucke_size 64;	# 주석 처리를 제거
	...
}

  • 옵션을 조정해야 하는 이유 Nginx는 이제 listen 지시문에 의해 포트 번호 80으로 들어오는 요청들에 대해 server_name 값과 정확하게 일치하는 서버 블록을 찾으려고 시도합니다. 만약 server_name을 추가할 때 해시 버킷 메모리 문제가 발생할 수 있기에 /etc/nginx/nginx.conf 파일에서 옵션을 조정하였습니다.

10. 새로 생성한 파일 활성화

서버블록까지 생성하였으니 새로 생성한 파일을 활성화하자
sudo ln -s /etc/nginx/sites-available/{도메인이름} /etc/nginx/sites-enabled/

예시 : sudo ln -s /etc/nginx/sites-available/[springworld.site](http://springworld.site/) /etc/nginx/sites-enabled/

도메인 주소 뒤에 한칸 공백이 있다. 조심하자

기본 구성 파일 삭제

바로 연결하면 연결이 되지 않기 때문에 Default 파일을 삭제하자

sudo rm  /etc/nginx/sites-available/default
sudo rm  /etc/nginx/sites-enabled/default

11. Nginx 재시작

Nginx에 대해 구문 오류가 없는지 테스트하고, Spring Boot 프로젝트와 함께 재시작하자

sudo nginx -t
sudo service nginx reload
java -jar {jar 파일명}.jar

java -jar {jar 파일명}.jar 실행이 안된다면 build/libs에 가서 실행하자

그 후에 도메인 주소로 접속하면 잘 작동된다.

만약 잘 안된다면 과감하게 nginx 삭제 후 다시 설치하자. 에러핸들링보다는 이게 생산성이 더 높다.

무중단 배포(백그라운드 실행)

nohup java -jar {jar 파일명}.jar &
이 명령어로 우분투 터미널의 세션이 종료되었을 때도 jar파일이 멈추지 않고 실행하게 한다

여담으로 나중에 포트폴리오에 작성할 때 “EC2 HTTPS 배포”처럼 적지말고 무중단 배포환경 구축이라고 표현하자

12. HTTPS 연결

Let’s Encrypt를 사용하자

#스냅 패키지 설치
sudo snap install core
sudo snap refresh core

#certbot 패키지 설치
sudo snap install --classic cerbot

#명령어 사용 편의를 위해 심볼릭 링크 생성
sudo ln -s /snap/bin/cerbot/ /usr/bin/cerbot

#버전 확인
crertbot --version

  • certbot이란 수동 관리되는 웹사이트에서 자동으로 Let’s Encrpt 인증서를 사용하여 HTTPS를 적용시키는 오픈소스 소프트웨어로 Let’s Encrypt에서 함께 제공한다.

인증서 발급
아래의 구문으로 인증서를 발급받자

sudo certbot --nginx -d [example.com](http://example.com/) -d [www.example.com](http://www.example.com/)

이메일 주소 입력하고 Y, Y를 선택하자

만약 내가 www.도메인.com을 route53에 하나라도 지정하지 않았다면 certbot은 인증서를 발급해주지 않는다.

하나의 도메인 주소만 지정했기에 sudo certbot --nginx -d [example.com] 구문을 입력했다.

Let’s Encrypt 3개월 후 만료되지만 아래 명령어로 Certbot이 자동으로 설정하도록 변경 가능하다.

sudo certbot renew --dry-run

EC2 인스턴스 인바운드 규칙 추가

Https를 적용하기 위해 인바운드 규칙에서 443포트를 열자

그러면 도메인 주소 창 옆에 자물쇠로 잘 적용된 것을 볼 수 있다.

만약 잘 안된다면 nginx를 껐다가 키자

$ sudo systemctl daemon-reload && sudo systemctl restart nginx

무중단 배포(백그라운드 실행)

nohup java -jar {jar 파일명}.jar &

부록_Maven && AWS 인증서 발급

Spring Boot 배포하기 (Nginx, HTTPS 설정)

부록_RDS 생성

https://spiny-orbit-764.notion.site/3c7efdb0cd974c8a82fd1e6cb75b10ce

profile
피자, 코드, 커피를 사랑하는 피코커

1개의 댓글

comment-user-thumbnail
2024년 1월 7일

선생님 많은 도움 받았습니다... 감사합니다....

답글 달기