[AWS]AWS 활용한 실습 프로젝트

신동혁·2022년 11월 21일
1

AWS

목록 보기
2/2

1.AWS 실습 프로젝트 개요

1) 주제

번호판을 위변조한 차량을 탐지하여 보완을 강화한 주차 관리 시스템을 설계한다.
깃 주소 : https://github.com/SHINDongHyeo/Anti-spoofing-car-project

2) 아키텍처

3) AWS 이용 파트

  1. AWS S3
    S3는 Simple Storage Service의 줄임말로 AWS에서 제공하는 파일 저장 공간이라고 생각할 수 있다. 이 프로젝트에서는 S3에 입출차 이미지, crop된 차량 이미지, 차량 원본 이미지를 저장할 것이다.
  2. AWS EC2
    EC2는 Elastic Compute Cloud의 줄임말로 AWS의 서버용 컴퓨터 한 대를 빌리는 것으로 생각할 수 있다. 이 프로젝트에서는 EC2에 flask, spring boot, react를 각각 배포할 것이다.
  3. AWS RDS
    RDS는 Relational Database Service의 줄임말로 AWS에서 관계형 데이터베이스(RDBMS)를 제공해주는 서비스다. 이 프로젝트에서는 RDS를 이용해 mysql을 DB로 이용할 것이다.

2.AWS 구조

위의 프로젝트 아키텍처를 구성하기 위한 AWS 서버 구축은 아래와 같이 구성하였습니다.

1) VPC SET 구성하기

  1. VPC : Virtual Private Cloud
  • vpc는 자체 데이터 센터에서 운영하는 기존 네트워크와 아주 유사한 가상 네트워크입니다. VPC를 생성한 후 서브넷을 추가할 수 있습니다.

CIDR : Classless Inter Domain Routing

IP 주소를 할당하는 방법

CIDR 블록 : 할당된 IP 주소들의 모음 , 그룹

VPC가 사용할 IP 대역 혹은 범위

Tenancy : 해당 VPC에서 EC2 인스턴스를 생성할 때 전용 하드웨어를 사용 할 것인지 대한 여부 확인

전용 하드웨어를 통한 생성은 Dedicated ( 본 프로젝트는 x )

DNS Host Name 설정

DNS 설정 : 만드는 vpc 에서 생성되는 EC2 인스턴스 와 같은 리소스가 DNS Host Name을 사용할지 여부를 Check 하는 항목

  1. Subnet
  • 서브넷은 VPC의 IP 주소 범위입니다. 서브넷은 단일 가용 영역에 상주해야 합니다. 서브넷을 추가한 후에는 VPC에 AWS 리소스 배포할 수 있습니다.

하위 네트워크 Subnet 설정

  • 서브넷 구성은 VPC의 CIDR 블럭보다 작아야함

Subnet 구성을 완성 !

그러나, EC2 인스턴스 등이 생성될 수 있는 위치 ! 는 생성되었으나, EC2를 기동할만한 인프라 작동하긴 어려움 리소스들 사이, 외부 인터넷 사이 트래픽이 이동할 경로를 구성해 주지 않았기 때문

그러한 서비스를 제공하는 것이 게이트웨이와 라우트 테이블임

3.Internet GateWays 생성 및 VPC Attach
( IGW 생성 방법과 Attach 방법에 대한 POST입니다. )

  • 생성 후에는 인터넷 게이트웨이를 사용할 VPC에 Attach 해줘야함

  1. Route Table 생성
    Route Table : Network 간 통신에 있어서, 목적지 , 대상지 등으로의 데이터 패킷 이동정보를 구성하는 규칙 Subnet 에 위치한 EC2 인스턴스 리소스들이 Destination , 대상지를 통해 어떤 경로를 통해 트래픽이 설정되는 지 정하는 Table

일반적으로 Private , Public Subnet으로 구성한 후 Route Table을 분리하여야 하지만, AWS 아키텍처 설계 시간 문제로 인해 본 프로젝트에서는 단일 라우팅을 통해 Associate 하였음.

  • EC2 인스턴스가 외부 인터넷과 통신 할 수 있도록 라우터 테이블에 인터넷 게이트웨이를 추가

목적지가 0.0.0.0/0 ( Destination ) : 외부로 향하는 트래픽은 인터넷 게이트웨이를 통해서 나가라 !

즉, 트래픽이 인터넷 게이트웨이를 통해서 나감

172.30.0.0 (내가 설정한 VPC CIDR 블록) Target이 Local으로 되어있음 기본적으로 내 VPC CIDR내에서의 트래픽 이동이 가능하다.

인터넷 게이트웨이를 통해 나갈 수 있는 환경이 구성됨

기본적인 네트워크 환경 셋팅 끝

TIP) VPC 설정 이유

2) EC2 인스턴스 생성

  • 인스턴스 OS 및 버전

  • 인스턴스 유형 설정

  • 이 때 AWS를 통하여 다운로드 되는 PEM Key는 서버에 접속할 경우 필수이므로 잘 저장해둔다. 서버의 접속은 Putty를 통하여 진행하였는데 Putty의 경우 PEM을 PPK로 전환하여 Private Key를 다시 만들어서 사용했다. Putty를 사용한 서버의 접속은 후술
  1. 네트워크 설정

EC2 인스턴스에 대한 기본적인 네트워크 요소를 만들거나 Setting 함

    1. Auto - assign - public IP ( 퍼블릭 IP 자동 할당 ) - 자동으로 퍼블릭 IP를 할당할 것인지에 대한 여부
      Enable로 선택하면 Public IP를 자동으로 할당함
    1. 이전에 생성한 VPC와 Subnet을 선택했으며, 생성한 VPC의 보안그룹으로 설정하였다. 보안그룹이 없는 경우 보안그룹을 설정해야한다.

      보안그룹(방화벽)은 인바운드 규칙과 아웃바운드 규칙으로 나뉘는데 인바운드는 요청 , 아웃바운드 응답으로 생각하면 된다.
      대게, 요청에 까다로운 설정을 하도록 한다. 아래는 보안그룹 설정 예시.

  • 클라이언트와 통신하기 위한 보안그룹

Firewall ( security groups )

Instance Level 에서 Traffic을 제어하는 네트워크 요소

통신타입 , 프로토콜 , 포트번호

소스타입 : 액세스 권한 부여

등, 그 서버에서 요청하는 유형의 프로토콜의 출입통제를 설정한다.

  1. 인스턴스에 스토리지를 추가

AWS 블록 스토리지 서비스 EBS 볼륨 추가 → 용량과 타입 설정

상세한 옵션 값 확인이 필요한 경우 어드밴스드를 클릭하여 설정

※ 돈이 많이 나갈까봐 프리티어 + 낮은 볼륨의 스토리지를 구성하였으나,
서버 빌드 및 배포시에 많은 라이브러리들이 추가되어, 서버 운영 및 설치중 Out of Memory Error 발생 및 데이터 처리 시 부하심화가 확인되었다. 가급적.. micro , 8 보다 더 크고 좋은 리소스를 선택하도록 해야겠다.

어떻게든 지출을 아끼기 위해 옵션의 기능을 찾아보았다.

  • 도메인 조인 디렉토리 : 생성한 인스턴스 사용자 , 그룹 , 디바이스 등에 대한 정보를 저장하고 access를 관리하는 AWS 디렉토리 서비스에 포함 시킬 것인지 여부 * 기본설정

  • IAM 인스턴스 프로파일
    IAM : indentity Access Mangement : AWS 리소스에 대한 액세스 권한을 제어하고 관리하는 서비스
    자격증명 및 사용권한을 정의하는 정책 ( Policy ) * 기본설정

  • 인스턴스가 시스템 상태 확인에 실패하면 인스턴스가 이를 자동적으로 복구할지 설정하는 옵션

  • Shotdown Behavior : 운영체제 레벨에서 셧다운을 실행할 때 인스턴스를 STOP할 것인지 Terminate 할 것인지 정함

  • Stop - Hibernate behavior : 최대 절전 중지 방식 ( 연습 : Disalbe )
    인스턴스를 최대 절전 모드로 상태를 변경 하도록 설정

  • 인스턴스가 갑자기 종료되지 않도록 보호하는 옵션 ( Disable )

  • 인스턴스가 갑자기 중지되지 않도록 보호하는 옵션 ( Disable )

  • CloudWatch : 인스턴스 생성 시 클라우드 워치를 통해 인스턴스에 대한 지표를 모니터링 및 분석 가능함 무료 지표외에 세부 설정이 가능한 옵션 ( Disable )

  • Elastic inference
    딥러닝 처럼 하드웨어 가속화가 필요한 경우 추가 가능한 옵션 ( Check 안함 )

  • 필요에 따라 높은 성능의 CPU 성능이 필요한 경우 선택 ( 순간적으로 컴퓨터 성능을 부스팅 )
    돈 많이 나가니까 주의 ( Standard )

  • 배치 그룹이라고 불리기도함, 인스턴스를 만들 때 해당 인스턴스를 어디에 어떻게 배치할지를 결정하는 옵션

  • EBS 의 IO ( Input / ouput )와 인스턴스 다른 트래픽 간의 경합을 최소화 해서 EBS의 볼륨에 개선된 성능을 제공하는 옵션 , 제한된 인스턴스 타입에서 활성화 됌

    • EBS 장점

  • Capacity Reservation : 특정 가용 영역에서 사용할 인스턴스 용량을 미리 예약해 두는 것 내가 사용하고자 할 인스턴스의 용량 및 수량을 확보해 두는 것 ( None )

  • AWS 많은 서버 중 하나를 대여하기 때문에 물리적으로 다른 사용자와 같은 물리서버를 공유
    하여 인스턴스를 사용하게 될 수도 있음 하지만 물리적으로 서버를 분리하고자 할 경우
    전용 인스턴스 , 전용 호스트를 사용하고자 할 때 테넌시 옵션을 사용한다.
    일반적으로 안정적이며, 사용자와 기존에 가지고 있는 라이선스를 자유롭게 사용
    ( 단 , 추가 요금 발생함 )
    ( Shared )

  • 특별한 경우가 아니면 AWS가 구성하도록 두는게 좋음 ( 그냥 select 으로 두자 )

  • Nitro Enclave : 인스턴스 내에서 민감한 데이터를 보호하고 안전하게 처리할 수 있는 기능

  • AWS 라이선스 매니저에서 설정한 라이선스 구성을 인스턴스에 적용할 수 있는 옵션

메타데이터 액세스 : 인스턴스 메타 데이터를 액세스 할 수 있는지 체크 ( Enable )

메타데이터 버전 : V1 , V2 혼용

홉 제한 : V2 사용 시 TOKEN 응답에 관한 옵션 ( 연습 1 으로 설정한다 )

메타데이터에서 태그 허용 : 인스턴스가 메타데이터에서 인스턴스 태그에 대한 리소스 허용에 관한 옵션 ( Enable )

User Data : 인스턴스가 launch 되는 과정에서 root 권한으로 실행되는 스크립트

인스턴스가 생성 된 후에 자동으로 스크립트를 실행시키도록 설정

인스턴스 생성 완료 !

3) Elastic IP 설정하기

퍼블릭 IP를 자동으로 할당하지 않았으므로 없음
Elastic IP설정을 통해 EC2 인스턴스에 퍼블릭 IP를 할당하는 작업

네트워크 보더 그룹 서울 리전을 선택 ( 노스이스트 )

이 후 생성한 인스턴스를 지정해서 연결하면 끝 !

TIP

엘라스틱 IP 사용 이유

출처 : https://any-ting.tistory.com/71

4) PuTTY를 통해 서버에 접속하기 !

EC2 인스턴스에 접근하기 위해선 해당 인스턴스에 대한 Key Pair 가 필요하다!

인스턴스를 생성하는 과정에서 만들어진 key pair를 찾는다

PuTTy를 다운로드하세요 !
Windows의 64 bit Zip 으로 다운로드
https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

다운로드 완료 후

PUTTYGEN 실행

  1. LOAD 실행

  1. Key Pair 추가하기

    Putty gen은 PPK 확장자만 확인하도록 되어있어 모든 확장자 파일을 통해 PEM 등록

Save Private Key 버튼 누르기

저장할 키페어 이름으로 PPK 확장자로 저장

Putty에서 사용할 PPK 생성 완료 !
Putty 실행


Accept를 누른다 !

Login as : ec2-user 를 입력한다.
ubuntu 인 경우 : ubuntu 입력한다.

서버 접속 끝 !

위와 같은 형식 그러나 보안그룹은 다르게 설정하여,
Spring , Flask 인스턴스를 생성한다 !

5) RDS 생성하기 (관계형 데이터베이스)

MySQL 8.0.30 버전으로 생성하였으며, 보안그룹의 인바운드 규칙은 Database와 연결할 ( Spring Server EIP와 , 작업PC의 Mysql 3306을 연결한다. )

Database의 초기 접근 ID , PW 처음 Mysql 설치 시 ( root / ??? ) 같은 아이디라 생각하면 된다.

생성한 VPC 선택

보안그룹 설정 시 Database와 접근 가능한 서버를 설정하도록 하여야 하지만, 개발 시에 IP 환경의 변화로 우선 모두 오픈해두고 작업함

이 후 다른설정은 두고 생성 완료 !

Spring Server 및 Local PC ( InteliJ 에서 DB 연결해보기 )

Spring Server 에서 접속해서 Database

데이터베이스 정상 접속 확인 !

기존
mysql -u root -p 에서 -h [Database의 엔드포인트이름]
으로 진행하면 됩니당 !

인텔리제이에서 해보기

6) S3 생성하기 (이미지 저장용)

  1. 버킷만들기
    AWS S3에 접속 후 다음과 같은 화면에서 우측 상단에 버킷 만들기 클릭

  2. 버킷명, 지역 설정

  3. 권한 설정

  4. 기타 설정
    기타 설정 후 버킷 만들기 클릭

  5. 버킷 설정
    해당 작업을 통해 버킷 탭에 들어가면, 버킷 1개가 생성된 모습을 확인할 수 있을 것이다.(사진에서는 이미 만들어놓은 버킷들로 인해 4개가 이미 있는 모습이다)

    그럼 해당 버킷을 클릭해 들어가면 다음과 같은 화면이 출력된다. 권한 탭을 클릭한다.

    다음과 같이 버킷에 대한 권한을 설정해준다.

3.Flask 설계 및 배포

1) Flask 서버 설계

  1. app.py 파일 안에 핵심 로직 설계
    flask를 실행 시 가동될 파일을 app.py로 설정하고 해당 파일 안에 핵심 로직을 설계했습니다. (자세한 내용은 포스트 위쪽 깃 주소에서 코드와 리드미 참조)

  2. Flask - Spring Boot 서버간 통신하기 / curl 커맨드를 통해 데이터 입력받기
    이번 프로젝트에서 설계한 구조로 인해 Flask와 Spring Boot가 통신하며 데이터를 주고 받아야 했기 위해 requests모듈을 이용해 Spring Boot와 통신했다.
    또한 자동차가 주차장에 입차하는 상황을 구현해야 했는데, 직접 차를 입차시키고 이를 사진으로 찍어서 Flask 서버에 전송하는 것은 개발 단계에서 불필요하다고 판단하여 미리 저장된 차량 입차 이미지들의 경로 정보를 curl 커맨드를 통해 Flask 서버에 전송하면 이를 restful API인 flask_restful라이브러리로 처리하여 해결하는 방식을 이용했다.

    ex) Flask - Spring Boot 서버간 통신하기

    ############# < app.py에 car_in() 일부 내용 > #################
    import requests
    
    # 입차 함수
    @app.route("/carin")
    def car_in():
         ################### 내용 생략 ############################
    	try:
              flag=""
              ######## 이 부분에서 spring과 post통신하는 모습을 확인할 수 있다.
              response = requests.post('http://스프링주소', json={"accesscarnum": accesscarnum2, "inimg":inimg, "park_id":park_id}) 
              if response.status_code == 200:
                  print("첫번째 통신200확인")
                  print(response.text)  # false: 위변조 코드 실행 X, true: 위변조 코드 실행 O
                  flag = response.text
          except:
              print("첫번째 통신에러")

    ( flask-restful documentation : https://flask-restful.readthedocs.io/en/latest/ )

    • response = requests.post('http://스프링주소', json=제이슨데이터)
      이 명령어가 Spring Boot와 통신하는 핵심 코드다. 여기서 스프링 또한 EC2 인스턴스에 배포되었으므로 스프링이 올라간 인스턴스의 퍼블릭 IPv4주소 + 스프링에서 requestmapping으로 설정된 url값을 넣어서 입력해주었다.(ex. "http://16.167.71.296/api/caraccess/test")

    ex) curl 커맨드를 통해 데이터 입력받기

    1. cmd창에서 curl 커맨드를 이용해 json형식 데이터를 해당 주소로 GET 방식 통신하는 모습( 지금 생각해보니 해당 코드는 입차 이미지 경로값을 보내기만 하면 되는 부분이라 GET보단 POST방식이 더 알맞는 방식같다!)
    curl -d "{\"accesscarnum\":\"01neo0680\", \"spoofing\":\"False\",  \"park_id\":\"2\"}" -H "Content-Type: application/json" -X GET AWS_EC2_instance주소값/carin
    1. curl 커맨드에 적힌 주소로 실행되는 Flask 서버 속 함수 부분.
    ############# < app.py에 car_in() 일부 내용 > #################
    
    from flask_restful import reqparse
    
    # 입차 함수
    @app.route("/carin")
    def car_in():
         ################### 내용 생략 ############################
        # 특정 차량번호, 위변조여부 넣어주기
        reqParser = reqparse.RequestParser() ########### curl로 전송한 json파일 받아들임!
        reqParser.add_argument("accesscarnum") 
        reqParser.add_argument("spoofing", type=str, default="False") # False: 정상, True: 비정상
        reqParser.add_argument("park_id", type=str, default="1")
        print("reqParser설정완료")
        reqArgs = reqParser.parse_args()
        print("parse_args()완료")
        accesscarnum = reqArgs["accesscarnum"]
        spoofing = reqArgs["spoofing"]
        park_id = reqArgs["park_id"]
        print("accesscarnum : ",accesscarnum,", spoofing : ", spoofing,", park_id : ", park_id)

    ( flask-restful documentation : https://flask-restful.readthedocs.io/en/latest/ )

  3. S3에 이미지 업로드 / 다운로드
    S3에 이미지를 업로드하거나 S3에서 이미지를 다운로드하는 등의 S3 관련 작업들을 함수화하고 이런 함수들을 묶어서 my_s3.py라는 파일로 모듈화했다.

    ex) S3에 이미지 업로드하기

    ######################### < my_s3.py 일부 내용 > > ########################
    
    import boto3
    from botocore.exceptions import ClientError
    import uuid
    
    def send_s3(id, pw, s3_img_name, upload_path1, upload_path2):
        """
        [params]
            id = 아마존 엑세스 ID
            pw = 아마존 엑세스 PW
            s3_img_name = s3에(위 버킷 안에) 저장할 파일명
            upload_path = s3에 업로드할 이미지가 저장된 로컬 경로
        """
        s3 = boto3.client(
                    's3',  # 사용할 서비스 이름, ec2이면 'ec2', s3이면 's3', dynamodb이면 'dynamodb'
                    aws_access_key_id=id,         # 액세스 ID
                    aws_secret_access_key=pw)    # 비밀 엑세스 키
        try:
            uuid_val = uuid.uuid1()
            s3.upload_file(upload_path1,"ecore-parking-record-in-car",f"{s3_img_name}_{uuid_val}.jpg")
            s3.upload_file(upload_path2,"encore-parking-record-crop-car",f"{s3_img_name}_{uuid_val}.jpg")
        except Exception as e:
            print("S3에서 파일을 업로드하는 도중 문제 발생!!!!!!!!!!!!!!!!!!!!")
            print(e)
        return f"{s3_img_name}_{uuid_val}.jpg"

2) EC2에 Flask 서버 용 인스턴스 생성하기

위에서 설명한 EC2 인스턴스 생성하기 참조

3) Flask 서버 github를 통해 EC2로 옮기기

로컬 PC에서 완성한 Flask 파일을 EC2에 옮겨야 한다. 이때 해당 Flask 파일을 github에 업로드하고, EC2에서 git 명령어를 통해 Flask 파일을 다운로드받는 과정으로 파일을 옮긴다.

  1. github에 새로운 repository를 생성하고 완성된 Flask 파일을 업로드한다.

  2. ubuntu(사용할 EC2의 OS)에서 다음 명령어를 통해 설치 가능한 패키지 목록을 최신화해준다.

    $ sudo apt-get update
  3. ubuntu에 git 설치

    $ sudo apt-get install git 
  4. git설치 확인

    $ git --version
  5. git clone해오기

    $ git clone 깃주소입력
  6. requirements.txt를 통해 필요한 라이브러리 설치

※ 발생했던 문제점 ※
예전부터 github에 있는 코드를 clone할 때 requirements.txt라는 파일을 본 적이 몇 번 있다. 이는 해당 코드를 실행하기 위한 패키지들을 정리해놓은 텍스트 파일이었고 readme에 작성된 가이드대로 pip install -r requirements.txt 명령어를 통해 필요한 패키지들을 설치했었다.

이번 프로젝트에서는 내가 코드를 다운받는 입장이 아닌 업로드하는 입장이여서 다운받아야 하는 패키지를 정리한 requirements.txt 파일을 만들어야 하는데, 이 텍스트 파일을 직접 모든 패키지명을 타이핑하는 것으로 생각했고 너무 비효율적인 작업이라고 판단해 requirements.txt 파일을 만들지 않았고, 결국 직접 모든 패키지들을 각각 pip 명령어를 통해 다운받아서 프로젝트를 진행했었다.

하지만 가상환경 내에 존재하는 패키지들을 텍스트 파일 형식으로 정리해 requirements.txt 파일을 만드는 명령어를 뒤늦게 알게 되었고, github에 코드를 올릴 때는 이 텍스트 파일을 올리는 것이 기본이라는 사실을 알게 되어 이를 공유하기 위해 사용법을 정리해본다.

  1. 가상환경의 패키지들 requirements.txt 파일로 정리하기
# 원하는 가상환경을 activate하고, 다음 명령어를 실행한다.
# 그럼 현재 위치한 경로상에 패키지명들이 담긴 requirements.txt 파일이 생긴다.

$ pip freeze > requirements.txt

# 만들어진 requirements.txt 파일은 github에 코드를 업로드할 때 같이 올려주어 
 코드를 다운받는 사용자들이 코드에 사용된 패키지를 손쉽게 다운할 수 있게 해주어야 한다.
  1. requirements.txt 파일 속 패키지들 설치하기
$ pip install -r requirements.txt

출처 : https://velog.io/@juno0713/Spring-Security-JWT-React-08.-%EB%B0%B1%EC%97%94%EB%93%9C-%EB%B0%B0%ED%8F%AC

Spring Boot 배포에 앞서 상기 Velog 개발자님의 포스팅을 기반으로 서버에 배포를 하였습니다.

4.Spring Boot Server에 Build 하기

1) Ubuntu Server Set up 하기

$ sudo apt-get update
  • 메모리 스와핑
    이후 해야할 과정은 메모리 스와핑이다. 이는 하드디스크를 가상 메모리로 전환시켜 램처럼 사용하는 것을 뜻한다.
    이건 다른 블로그나 책 등에서 배포할 때 잘 설명하지 않는 부분인데, 만약 자기가 AWS의 프리티어를 사용하고 있다면 난 메모리 스와핑이 필수라고 생각된다. 왜냐하면 실제 빌드를 할 때 이 부분에서 램 부족 문제로 진행되지 않는 경우가 부지기수기 때문이다.

--> 실제로 메모리 스와핑을 하지 않은 경우 t2 Micro 버전에서 메모리 오버의 문제가 발생하였다.
작은 서버를 가용하게 된다면 적당한 가상메모리를 설정하는게 좋을 것 같다..!

먼저 스와핑을 진행할 파일을 생성해주자.

$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ sudo swapon -s
$ sudo vi /etc/fstab

vi 편집기에서 Insert(i) 모드로 들어간 후 수정 후 :wq를 통하여 나온다.

/swapfile swap swap defaults 0 0

이 후 free 를 서버에 입력하여 가상메모리가 적용 되었는지 확인

2) JAVA 설치

$ sudo apt list | grep openjdk

11버전에 맞는 jdk 설치

$ sudo apt-get install openjdk-11-jdk

ubuntu 서버에 환경 변수를 셋팅하는 방법은 아래 포스팅을 참조하였습니다.

https://unit-15.tistory.com/114

$ sudo apt-get update
$ sudo apt-get upgrade

$ java -version
$ javac -version

$ vim /etc/profile

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64      // 본인의 자바 설치 경로
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=$CLASSPATH:$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar

$ source /etc/profile

$ vim ~/.bashrc

편집하고 나온다
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64      // 본인의 자바 설치 경로
export PATH=${PATH}:${JAVA_HOME}/bin

$ source ~/.bashrc

$ echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-amd64

3) Gradle 설치

$ sudo apt install zip
$ curl -s "https://get.sdkman.io" | bash
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
$ sdk version
$ sdk list gradle
$ sdk install gradle 7.5.1

4) Github에서 Code Clone하기

  • github에서는 SSH로의 Clone 진행 시 보안의 문제로 Token을 발급 받아서 진행해야한다.

github에서의 토큰 발급은 다음과 같이 진행한다.

main brunch에서 Clone 하는 경우 통상 Repo만 체크해서 발급...

$ git clone [프로젝트 코드 주소]

이 후 서버에서 git clone을 하게되면 ID와 Password를 치는데,
이때 Password는 발급받은 Token을 입력하면된다 !

gradlew 가 있는 디렉터리까지 이동한 뒤

$sudo chmod +x ./gradlew

권한 부여 후

클린 테스트 시작

$sudo ./gradlew clean test

대게 DDL 예약어 때문에 Warning이 발생하는 경우가 있다.
첫 배포시에 Hibernate 관련한 오류가 발생했다. 지정한 RDS Database가 연동이 되지 않아 계속 배포 실패했었다 ㅠㅠ 결국 AWS의 RDS 설정을 다시하게 되었는데 이러한 상황이 되지 않으려면 서버에서 먼저 RDS연동을 확인하고 배포하자!

테스트 빌드가 끝났다면 실제 빌드

$ sudo ./gradlew build

$ sudo java -jar [ jar파일명 ]

성공 ~

포트 포워딩 !
이걸 설정하면 80포트에서 8080 포트로 바로연결하게 끔 할 수 있다.

$ sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

백그라운드 배포

$ nohup java -jar [파일이름].jar &

스프링 배포 완료 !

5.react 배포하기

React 서버 접속하여 React를 구동할 수 있는 환경을 셋팅한다
이 중 node js의 설치와 npm install이 필수 !

node js의 경우 최신의 16버전에서 진행 시 npm이 설치되지 않는 이슈가 발생하여,
14버전으로 Set up 하였다.

추가로 npm install 시 --verbose를 사용하여 install 시 발생하는 이슈에 대한 log를 확인 하도록 한다.

sudo apt-get install systemd
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y build-essential
sudo apt install npm
sudo npm install --verbose

로컬에서의 빌드이다보니, nginx , apach2 , jenkins등의 서버를 별도로 설치하지 않았으며,

설치가 완료된 이 후 sudo npm run build 을 통하여 빌드가 정상적으로 되는지 확인

이 후 serve -s build를 통하여 react 서버 기동을 완료하였다.

접속 성공 !

6.시연영상

profile
개발취준생

0개의 댓글