본문 바로가기
Backend

Aws Ec2에 무료로 spring 서버 올리기

by 뜨거운 개발자 2024. 10. 10.

0. 시작하며

이 글에서 aws 회원가입까지는 다루진 않겠다.

ssh 연결부터, spring 서버에 CI/CD를 하는 방법에 대해서 다루겠다.

생각하는 구조는 다음과 같다.

Ec2에 spring을 띄우고 Rds를 띄우고 redis를 띄우고 각각을 연동하는 방법을 알려주겠다.

우리는 가난하기 때문에 무료로 모든 걸 세팅하는 방법에 대해서 다루겠다.

1. Ec2 만들기

인스턴스를 다음 그림처럼 만들어준다.

1.1 운영체제 정하기

여기서 운영체제를 amazon Linux로 만들어도 되고, ubuntu로 만들어도 된다.

사실 두개 다 상관없지만 이 게시물에서는 ubuntu로 만들어준다. 명령어가 더 익숙하기 때문이다. 만약 amazon Linux 명령어가 더 편하거나 다른 이유가 있다면 amazon Linux를 사용해도 된다.

 

1.2 키 페어 생성

ssh 연결을 위해 키페어를 만들어서 다운로드 받자. 필자는 .ssh 폴더로 해당 pem 파일을 옮겨줬다.

1.3 보안그룹 설정

다음과 같이 보안 그룹을 생성해서 할당해준다.

그러면 시간이 지나면서, 인스턴스가 실행상태가 되게 된다.

 

2. SSH 연결하기

2.1 .pem 파일 옮기기

일단 .ssh 폴더로 pem 파일을 옮겨준다.

2.2 ssh config파일 수정

해당 폴더 안에 config파일을 만져준다.

 

2.3 .pem 파일 권한 수정

다음과 같이 적어주고 ssh 하고 host를 적어줍니다.

 

하지만 그냥 하게 되면 다음과 같이 pem파일에 너무 권한이 많다고 나오기 때문에 권한을 chmod로 바꿔준다.

이렇게 권한을 볼 수 있다.

2.4 ssh 연결 성공

 

다음과 같이 ssh연결이 된다.

탄력적 IP

탄력적 IP는 한 개만 사용할 때에는 요금이 청구되지 않지만, 서비스와 연결되어 있지 않으면 요금이 청구되는 걸로 알고 있었지만, 
2024년 2월 1일부터 서비스 연결 여부에 관계없이 모든 탄력적 IP 주소(IPv4)에 대해 시간당 $0.005의 요금이 부과된다고 한다.

https://aws.amazon.com/ko/blogs/aws/new-aws-public-ipv4-address-charge-public-ip-insights/

 

New – AWS Public IPv4 Address Charge + Public IP Insights | Amazon Web Services

We are introducing a new charge for public IPv4 addresses. Effective February 1, 2024 there will be a charge of $0.005 per IP per hour for all public IPv4 addresses, whether attached to a service or not (there is already a charge for public IPv4 addresses

aws.amazon.com

2.5 ++) Time Zone 설정해주기

sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime

ec2 는 기본으로 time zone이 미국으로 되어있으니 한국으로 바꿔주자.

3. 스왑 메모리 설정하기

3.1. swap 파일 확인

스왑 파일이나 파티션이 존재하는지 확인합니다.

sudo free -m
sudo swapon -s


두 명령어를 실행했을 때 swap 관련 내용이 보이지 않으면 다음 과정을 진행한다.

만약 swap이 작동중이라면, 아래 명령을 실행해 작동을 중지합니다.

sudo swapoff -a

 

3.2. swapfile 생성

swap을 하기위한 swapfile을 생성합니다.

sudo fallocate -l 2G /swapfile

 

-l 뒤에는 swapfile의 용량을 입력하면 됩니다. 2G를 입력하면 메모리 외에 추가로 2G의 가상 메모리를 사용할 수 있습니다. 이후 root 디렉터리에 swapfile이 생성됩니다.

 

3.3 swap 활성화


swapfile의 권한을 수정한 뒤, 해당 파일이 swap으로 동작하도록 만듭니다.

sudo chmod 600 /swapfile # 권한 수정
sudo mkswap /swapfile    # 활성화 준비
sudo swapon /swapfile    # 활성화


swap 메모리가 생성되었지만, 이를 재부팅해도 계속 사용하려면 /etc/fstab 파일을 수정해야 합니다. 해당 파일을 열어 아래 내용을 추가합니다.

sudo nano /etc/fstab # 파일 편집
## 내용 추가
/swapfile swap swap defaults 0 0

다음과 같이 스왑 공간이 나온 걸 볼 수 있다.

3.4. swap 파일 삭제

sudo swapoff -v /swapfile # 스왑 비활성화
sudo nano /etc/fstab      # 파일 실행 후 아래 라인 삭제
/swapfile swap swap defaults 0 0
sudo rm /swapfile # swap 파일 삭제

 

스왑을 비활성화해야하는 경우가 종종 있다. 

예를 들면 쿠버네티스를 사용할 때 등이 있는데 그런경우 스왑을 꺼줘야할 때 이걸 사용해주면 된다.

https://haward.tistory.com/249

 

[k8s] kubectl 명령어가 동작하지 않을 때 (왜 쿠버네티스는 스왑 메모리 사용을 허용하지 않는가?)

문제 상황kubectl get podskubectl 명령을 실행했는데 갑자기 다음과 같은 로그가 나왔다.E0826 15:09:19.548029 5807 memcache.go:265] couldn't get current server API group list: Get "https://192.168.64.4:6443/api?timeout=32s": dial tcp

haward.tistory.com

 

4. RDS 만들기

4.1. 손쉬운 생성으로 db 생성

 

 

rds이름을 식별자로 이름을 지어주고 인스턴스 크기를 프리티어로 설정해주자.

4.2. rds 암호 설정 및 Ec2 연결 설정

데이터베이스를 public ip로 만들면 비용이 발생하기 때문에 ec2인스턴스에 rds를 연결해줍니다.

다음과 같이 db가 생성됩니다.

 

4.3 ssh Tunneling Rds 연결 후 확인

intelij에 database로 rds를 연결해줍니다.

다음과 같이 datasource에 mysql을 누르고

SSH/SSL 부분에 Ec2와 연결햇 ㅓ 해야하기 때문에 Use SSH tunnel을 켜줍니다.

거기서 Host에 Ec2의 ip랑

username을 올바르게 적어줍니다. 

만약 Amazon Linux를 썼다면 ec2-user로 접속하면 됩니다.

그리고 keyPair를 .ssh 에 넣어뒀으니 그쪽으로 선택해줍니다.

 

이후, host 에 rds주소값을 넣어주고 port랑 비밀번호를 적어주고 연결을 해준다.

 

4.4 application-prod.yml 파일 설정

spring:
  profiles:
    active: dev

server:
  port: 8080

springdoc:
  packages-to-scan: com.groomiz.billage
  default-consumes-media-type: application/json;charset=UTF-8
  default-produces-media-type: application/json;charset=UTF-8
  swagger-ui:
    path: /
    disable-swagger-default-url: true
    display-request-duration: true
    operations-sorter: alpha

 

원래 내가 사용하던 application.yml파일이고 여기서 profile을 dev가 아닌 prod로 바꾸면 배포용 yml파일로 바꿀 수 있다.

application-prod.yml파일 생성 후 해당 파일에 db 설정값에 올바른 값을 놓는다.

 

spring:
  datasource:
    url: 'aws rds url:port/dbname'
    username: 'aws rds user name'
    password: '비밀번호'

 

파일에 이걸 잘 넣어주자.

 

5. Redis사용을 위해 Elastic Cache 생성하기 

5.1. Redis 생성하기

프로젝트에서 refresh Token을 redis에 보관하고 사용한다.

따라서 이를 위해 redis를 aws에 만들어서 사용하자.

redis를 사용하려면 aws의 ElasiCache를 사용해야한다.

이것 역시 프리티어가 있기 때문에 그걸 믿고 사용해준다.

다음과 같이 Redis OSS 캐시를 만들어주자.

서버리스는 프리티어가 없기 때문에 프리티어로 자체캐시 설계로 연결해준다.

이 부분에서 클러스터 모드를 비활성화 해주자.

우리는 개발 서버를 띄우는게 목적이기 때문이다.

노드 유형을 cache.t2.micro로 해서 프리티어 용량으로 사용해준다.

이렇게 만들어주면, Creating 상태가 되고 기다리면 생성된다.

5.2. application-prod.yml 변경

이후 redis에 해당하는 application-prod.yml을 바꿔주자.

spring:
  datasource:
    ...
  data:
    redis:
      host: '엔드포인트'
      port: 6379

5.3 보안 그룹 설정하기

생성이 완료되는 동안 조금의 시간이 걸린다.

생성시에 보안그룹은 default로 해주었는데, 보안그룹을 새로 만들어야 한다. (6379 포트로 접속을 허용해야 하므로)

 

EC2 > 보안그룹 > 보안그룹 추가 > 인바운드 설정 > 6379 추가하기

보안그룹 이름, 설명을 필수 기재 해야하는데, redis-security 로 설정했다

아까 Redis를 처음만들 때 defaul로 되어있던 보안그룹을, 4번에서 만든 보안그룹으로 수정해주어야 한다.

다시 Elastic Cache 대시보드로 가서 우리가 만든 클러스터를 선택하고, 위에 작업 > 수정 버튼을 누른다

 

 

5.4  Ec2에서 redis접속하기

5.4.1. Ec2에 접속하기

먼저 EC2에 접속한다. (위에서 작성한 SSH 방법으로 접속)

 

5.4.2 Gcc 설치

5.4.3 make 설치

sudo apt install make

5.4.4 redis cli 설치

wget http://download.redis.io/redis-stable.tar.gz && tar xvzf redis-stable.tar.gz && cd redis-stable && make
sudo apt install redis-tools

5.4.5. redis 에 접속하기

redis-cli -h  [기본 엔드포인트]

 

여기서 기본 엔드포인트도 그렇고 리더 엔드포인트도 결국 같은 url을 가리킬 것이다.

이런식으로 엔드포인트를 입력해주면 들어가서 확인 할 수 있다.

다음과 같이 접속이 된다면 redis 설정까지 완료된 것이다.

간단한 명령으로 redis에 데이터를 추가하고 삭제해볼 수 있다.

5.5 Spring에 redis 설정 해주기

역시나 spring서버를 띄우기 위해서는 redis도 config에 잘 적어줘야한다.

 

 

 

6. Spring 서버 빌드해서 Ec2에서 실행하기

6.1. gradlew 로 스프링 빌드하기

로컬에서 다음 명령을 사용해서 스프링을 빌드해준다.

 ./gradlew build -x check --parallel

이후 scp를 사용해서 파일을 업로드 해줍니다.

6.2. scp로 jar 파일 옮기기

 scp -i ~/.ssh/billage_global.pem billage-0.0.1-SNAPSHOT.jar billage:~/

다음 명령을 사용해서 파일을 옮겨준다.

이렇게 올려주고 ssh 로 연결해서 실행해보자.

다음과 같이 접속하면 jar 파일이 있는 걸 볼 수가 있다.

 

 

6.3. java 및 jdk 설치 

우리는 ec2에서 jvm을 이용해서 스프링 서버를 띄울 것이어서 java 설치가 필수적이다.

# 업데이트
sudo apt update

# 업그레이드
sudo apt upgrade

# 모든 버전 목록 조회
sudo apt list openjdk*

sudo apt install [리스트에 나오는 jdk버전]

 

 

6.4 spring 서버 실행하기

java -jar billage-0.0.1-SNAPSHOT.jar

이 명령을 사용해서 spring이 제대로 올라가는지 확인해보자.

여기서 db관련 내용이 잘 못 설정되어있다면 이걸 하면서 설정을 제대로 하도록 하자.

 

7. Nginx로 서버 띄우기

7.1. Nginx 관련 커맨드

nginx 관련된 명령어들을 미리 저장해두고 기억하자.

nginx -t					# nginx 설정 파일의 문법이 올바른지 확인

sudo service nginx status 	# nginx 상태 확인

sudo service nginx start	# nginx 실행
sudo service nginx restart	# 중지 후 재실행
sudo servcie nginx reload	# 수정된 파일 적용하여 연결을 끊지 않고 재실행
sudo service nginx stop		# nginx 중지

# 기본적으로 Nginx는 서버가 부팅될 때 자동으로 시작됩니다.
sudo service disable nginx	# 자동 시작 비활성화
sudo service enable nginx	# 자동 시작 활성화

7.2 Nginx 설치

nginx 를 설치해주고 

sudo apt-get update
sudo apt install nginx -y
nginx -v
sudo service nginx status

 

7.3. Ec2 ip로 접속해보기

다음과 같이 나온다.

7.4 무료 도메인 발급받아서 연결해주기

나중에 HTTPS를 사용하기 위해서 무료로 도메인을 발급받을 수 있는 사이트를 소개하겠다.

 

https://www.duckdns.org/domains

 

Duck DNS

Duck DNS free dynamic DNS hosted on AWS news: login with Reddit is no more - legal request support us: become a Patreon

www.duckdns.org

사이트는 duck DNS로 무료로 도메인을 제공한다.

개발용으로 사용하기에는 안성맞춤인 사이트. 구글 계정 하나 파서 그걸로 가입해서 관리하자.

여기에 Ec2 Ip를 적어주면 알아서 연결이된다.

7.5 sites-available 파일 수정하기

다음과 같이 sites-available파일을 만들어서 넣어준다.

 

server {
        listen 80; // 80 포트로 받고
        listen [::]:80;


        server_name 도메인 주소;

        location / {
                proxy_pass http://localhost:8080; // 8080포트로 접근 시킨다.
                proxy_set_header Host $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 Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }
}

 

여기서 도메인 주소에 http붙히면 동작 안 했었다. 주의하자.

 

7.6 sites-enabled link 설정

sudo ln -s /etc/nginx/sites-available/파일 명 /etc/nginx/sites-enabled/파일 명

 

 

7.7. nginx 재시동

    sudo systemctl start nginx

설정을 바꿨으면 sudo nginx -t 로 설정파일이 올바르게 실행되는지 한번 확인해보고

재시동 명령을 사용해준다.

 

7.8. Spring 서버 접속하기

 

이후 접속을 진행하면 다음과 같이 나오는 걸 볼 수가 있다.

7.9 백그라운드에서 spring 서버 띄우기

nohup java -jar billage-0.0.1-SNAPSHOT.jar > application.log &

다음과 같은 명령을 사용해서 billage 어플리케이션을 실행해준다.

 

8. GitHub Action으로 CI/CD 설정하기

8.1. 동작흐름 설명

동작 흐름은 다음과 같다.

  1. Github Actions 에서 코드 빌드 (테스트는 CI 에서 했다고 검증했다고 판단하여 생략)
  2. AWS 인증
  3. 코드 압축해서 AWS S3 에 업로드
  4. AWS CodeDeploy 실행하여 S3 에 있는 코드 EC2에 배포

8.2. Ec2 설정 추가

  1. Tag 추가 (CodeDeploy 에서 어떤 인스턴스에 실행할 지 구분하는 값)
  2. IAM 역할 등록
  3. EC2 서버에 CodeDeploy Agent 설치

8.2.1. Tag 추가

CodeDeploy 를 생성할 때 어떤 인스턴스에서 수행할 지 구분하는 값으로 태그를 사용하기 때문에 추가가 필요하다.

기존에 인스턴스 생성할 때 태그까지 같이 생성했다면 이 과정은 생략해도 괜찮습니다.

 

-- 2024.10.10 github action 전까지 작성

++) 추가 예정 Github Action + Https 설정

https://bcp0109.tistory.com/363

 

Github Actions CD: AWS EC2 에 Spring Boot 배포하기

Overview 애플리케이션을 개발하면 외부에서도 접근 가능하도록 클라우드 환경에 배포합니다. 이전에 포스팅 했던 AWS 1편에서는 마지막에 scp 명령어로 로컬에 존재하는 빌드 파일을 EC2 인스턴스

bcp0109.tistory.com

https://velog.io/@jihyunhillpark/2.-spring-boot-%EA%B8%B0%EB%B0%98-%EC%95%B1-%EB%B0%B0%ED%8F%AC-Cerbot-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EB%B0%9C%EA%B8%89%EA%B3%BC-SSL-%EC%A0%81%EC%9A%A9

 

728x90