-
[TIL] 스파르타) Ch.3 개인 과제 배포 (AWS EC2)TIL-sparta 2024. 5. 16. 21:32
> AWS EC2 서버에 Node.js 프로젝트 서버를 배포하는 과정에서 배운 것들을 정리해보았다.
학습 키워드: aws ec2, node js, git, deploy, ssh, scp
1. AWS EC2 서버 세팅하기
1) What is it?:
프로젝트의 필수 작업들을 마치고 요구 사항에 맞춰 AWS EC2 서버에 node 앱을 배포하는 과정을 거쳤다. 예전 프로젝트는 배포를 직접 하지는 않았고, 작은 건은 어지간하면 Github Pages를 이용했기 때문에 간단하게 해결했었다. 그러나 이번에는 처음으로 혼자 외부 linux 서버에 bash를 통해서 배포 해봤는데 생각보다 복잡해서 시간이 오래걸렸다.
2) Basic settings:
AWS 회원 가입을 마치고 환경 설정에서 서버 지역을 알맞게 수정해준 후 EC2 콘솔에 진입하면 dashboard에 Launch Instance라고 적혀있는 주황색 버튼이 있다. 이 버튼을 통해 우선 instance를 생성해줘야 한다.
다른 부분은 다 기본설정을 사용하고, 몇 가지 설정만 변경해줬는데, 일단 key pair를 생성 해줘야한다. Create new key pair를 눌러서 키의 이름과 암호화 방식을 골라주고, SSH나 PuTTy 중 사용할 bash에 맞춰 format을 바꿔주면 된다. 생성이 완료되면 드롭다운에서 생성된 키를 선택해준다. 해당 키 파일은 자동으로 다운로드 받아진다.
두 번째 설정은 Security Group인데, 이 부분이 서버의 inbound/outbound 트래픽을 ip에 따라 제어해준다. 현재 프로젝트는 웹 서버이므로 관리 포트인 SSH는 My IP로 설정하고, HTTP와 HTTPS의 트래픽 허용 체크박스를 눌러준다. (추후에 Node 서버를 업로드하면 app이 listen하는 포트의 번호 또한 TCP Any IP로 inbound 허용 설정을 해줘야한다.)
하단으로 쭉 내려가서 Launch Instance를 누르면 인스턴스의 생성이 완료된다.
이번 프로젝트에서는 MongoDB를 사용했는데, DB에도 IP에 따른 접근 제한이 걸려있으므로 Atlas의 좌측 메뉴 하단에 있는 Network Access에서 EC2 서버의 public IP를 허용해줘야 한다.
3) Connect to EC2 server:
설정이 완료되면 이제 SSH 포트를 통해 서버에 연결해줘야한다. EC2 콘솔 좌측의 instances를 눌러서 진입하고, 생성해둔 인스턴스의 Instance ID를 누른 뒤 우측 상단에 표시되는 Connect 버튼을 눌러준다. 여기서 SSH Client 탭을 눌러보면 하단에 Example: 과 함께 서버 연결에 사용되는 명령어가 있다. 좌측의 복사 버튼을 눌러 복사해두자.
chmod 400 "yourKey.pem" ssh -i "yourKey.pem" [user]@[Server Public IP OR DNS]
연결에는 Git Bash를, key pair에는 RSA와 .pem 형식을 사용했다. 다운로드 받아둔 key의 위치로 이동하여 chmod 400으로 key를 보호해주고, 위에서 복사해둔 명령어를 입력하면 서버와 연결되어 root 디렉토리에 진입하면 된다.
2. Node.js 앱 배포하기
1) Basic Settings:
# update instance > sudo yum update # get into sudo root > sudo -s # install nvm > curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # load nvm > source ~/.bashrc # (alternative) activate nvm # > . ~/.nvm/nvm.sh # install latest version of Node.js > nvm install --lts # install git > yum install -y git # version check > node -v > npm -v > git -v # exit sudo -s > exit
위 명령어들을 순서대로 실행해주자.
방금 생성했기 때문에 첫 번째 줄은 별다른 작업을 해주지는 않는다. 두 번째 명령어는 nvm을 설치해주고, 세 번째 명령어로 설치된 nvm을 활성화 해줄 수 있다. 네 번째 명령어는 최신 버전의 Node.js를 설치해준다. 그 다음 명령어로 git을 설치해주고, 마지막 명령어들로 설치가 제대로 되었는지 확인해주자.2) Deploy Key:
# create a deploy key on server > ssh-keygen -t ed25519 -f ~/.ssh/my_project_deploy_key -C "your_email@example.com" # cat the key and copy it > cat ~/.ssh/my_project_deploy_key.pub
다음은 deploy key를 생성해주는 작업이다. 첫 번째 명령어의 맨 끝에 있는 이메일 주소만 본인 이메일로 변경해주고 cat으로 deploy key를 확인하고 복사한다. 그 다음 Github의 repository 설정에서 좌측 하단에 있는 Deploy Keys에 해당 Key를 추가해주면 된다. 서버에서 repository로 push할 수 없게 하려면 write access 체크박스를 해제 해줘야한다.
Deploy key는 외부에서 SSH를 통해 repository에 접근할 수 있도록 허용해주는 용도인데, 사실 현재 프로젝트 repository는 visibility가 public으로 설정되어 있어서 deploy key가 필요하지는 않다. 추후 비공개 repo를 배포할 때를 대비하여 2)와 3)의 작업들에 대해 알아두도록 하자.3) SSH configuration:
# create a ssh config file > vim ~/.ssh/config > chmod 440 ~/.ssh/config
다음은 SSH config 파일을 생성해주고 vim 에디터에서 약간의 편집을 해줘야한다. Vim 에디터로 파일 작성이 끝나면 chmod를 이용해 읽기전용으로 설정해주는 것도 잊지 말자.
# config Host [some-name] github.com Hostname github.com IdentityFile /home/[user]/.ssh/my_project_deploy_key User git
실행된 vim 에디터(config 파일)안에 위의 내용을 복사하여 붙여넣고, [some-name] 부분에 구분할 수 있는 임의의 이름(예: my-project)을 입력(대괄호는 포함하지 않는다)해주면, 추후에 SSH를 통해 repository에 access 할 때 URL의 앞에 git@[some-name]: 을 붙여서 ItentityFile에 명시된 deploy key를 이용하여 접속하도록 유도할 수 있다. 위의 예시에서는 Host에 github.com도 추가되어있어 git@github.com: 으로도 동일한 작업을 할 수 있다. 적용 예시는 아래 4)를 참고하자.
IdentityFile에는 [user] 부분에 ec2 username(따로 변경 안했으면 기본 값은 ec2-user)을 넣어주면 된다. 작성이 완료되면 esc를 한 번 눌러주고 :wq를 입력한 뒤 엔터를 눌러서 저장과 함께 vim 에디터를 종료해준다.
4) Cloning Github repository (master branch):> cd ~ > git clone -b [branchName] --single-branch git@[some-name]:[gitUserName]/[repoName].git
마지막으로 git clone을 사용해주면 되는데, 개인 프로젝트 repo의 default branch가 현재 develop으로 설정되어 있기 때문에 -b master --single-branch 옵션을 추가해서 배포용 branch인 master를 clone해줬다. @ 뒤에 붙은 [some-name]은 위에서 config 파일에 적어준 [some-name]과 동일한 이름을 사용하면 된다.
예시) git clone -b master --single-branch git@my-project:donkim1212/ch3-item-simulator.git
5) Sending files to the server:# move files from local system to server: > scp -i "myKey.pem" .env [user]@[server public DNS]:/home/[user]/[git-project-folder]
서버에는 현재 DB access나 실행 포트 등의 정보가 담긴 env파일이 없으므로 scp를 이용해 해당 파일을 복사 해줘야한다. 편의를 위해 .pem파일이 있는 위치에 .env파일을 복사해 옮겨주고, 로컬 시스템의 bash에서 위의 명령어를 실행하여 서버로 파일을 옮겨주면 된다. [user]는 ec2 user이름, 그 뒤는 서버의 DNS 주소, 그 다음은 다시 ec2 유저 이름, 그리고 마지막이 git clone으로 생성된 폴더의 이름이다. 이제 다시 ssh로 서버에 접속하여 npm install --global yarn으로 yarn을 설치(yarn을 사용하는 경우만)해주고 yarn install로 모듈 설치 작업을 해주면 끝이다.
6) Other useful commands regarding deployment:# Unzipping a zip file > unzip your.zip # kills all node processes > killall node # if node process refuses to be killed > fuser -k [portNumber]/tcp # ex) fuser -k 3000/tcp # run node server on 'screen', which will keep the process on after disconnecting from ssh > screen > npm start # or if npm start not defined in package.json, > node app.js # check running process with LISTEN > netstat -anltp | grep LISTEN # or simply 'netstat -ltp' to get the similar result
- unzip 명령어는 zip파일의 압축을 해제해준다.
- killall node 는 실행중인 모든 node 프로세스를 종료해준다.
- 만약 위 명령어로 종료가 되지 않는다면 fuser를 사용해 포트를 사용중인 프로세스를 종료할수도 있다.
- screen 을 입력해주면 새로운 bash 스크린으로 진입하는데, 여기서 node 서버를 실행해주면 bash가 종료되더라도 프로세스가 종료되지 않고 유지된다.
- 마지막에 적어둔 netstat 명령어는 실행되어있는 프로세스 중 LISTEN 동작을 하고있는 TCP 프로세스의 목록을 불러와준다. 실행 중인 node 서버가 있는지, 어느 포트에서 동작하는지 확인할 때 유용하다. 이 명령어를 다른 곳에서 그대로 복사해왔는데, 사용된 옵션들이 무엇인지 간단하게 알아봤다.
a 옵션을 입력하면 모든 소켓을 대상으로 한다.
n: host 이름이나 port 이름 등에 대해서 원래의 문자열을 보여주도록 설정한다. (예를 들면 [::]:* 가 :::* 로 바뀌는 식)
l: listening 상태인 server 소켓을 나열하는데, established 상태인 경우도 포함한다.
t: tcp 소켓만 나열한다
p: 항목의 PID와 program 이름을 같이 출력해준다
grep LISTEN: git의 grep과 똑같은 기능인데, netstat 명령으로 찾아낸 항목 중 LISTEN이 포함된 항목만 추려준다.
- 하나하나 읽어본 후에 서버에서 테스트 해보니 현재 케이스에서는 ltp 옵션만을 사용하여 동일한 결과를 얻을 수 있었다.
--
REFERENCES:
> 개인 과제 specification
> 개인 프로젝트 repository
> dev.to, "Quick manul deploy to EC2 with github", EC2 서버 deploy key 설정
> medium.com, "CI/CD from Github to AWS EC2",
> amazon.com, "Prerequisites", Security Group Rule 항목 참고
> stackoverflow.com, "Git: Clone from a branch", 특정 branch를 clone하기
> stackoverflow.com, "...leave Node.js server on..."
728x90'TIL-sparta' 카테고리의 다른 글
[TIL] 프로그래머스) 138476 - 귤 고르기 (Java) (0) 2024.05.18 [TIL] 스파르타) Ch.3 개인 과제 리뷰, Node 강의 수강 (0) 2024.05.17 [TIL] 스파르타) Ch.3 개인 과제 - 3일 차 (Joi, git commit --amend) (2) 2024.05.15 [TIL] 스파르타) Chapter 3 개인 과제 진행 - 2 일차, git rebase (2) 2024.05.14 [TIL] 스파르타) Chapter 3 개인 과제 시작, MongoDB와 auto increment (0) 2024.05.13