ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • EC2로 Next.js 앱 배포하기
    Web/Build and Deploy 2021. 10. 6. 20:13
    반응형

    사실 글 자체는 Next.js에 크게 초점이 맞춰져 있지는 않다.

    EC2를 이용해서 앱을 배포하는 것이 메인 주제이지만, 굳이 'Next.js 앱' 이라고 덧붙인 이유는

    Next.js는 별도의 서버 로직을 작성할 필요가 없기 때문이다.

     

    물론 Customizing을 원한다면 직접 서버 로직을 작성해서 EC2에다 배포해도 되긴 하지만,

    대부분의 경우에는 Next.js에서 기본으로 제공해주는 서버 로직을 사용해주는 것이 좋다고 한다.

    서버 로직을 직접 작성하면, Next.js의 기본 서버 로직이 갖고 있는 성능 최적화의 이점이 사라지기 때문.


    1. EC2 콘솔에 접속해서 인스턴스 시작 버튼 누르기

    2. Amazon Machine Image(AMI) 선택하기

    AMI는 인스턴스를 시작하는 데에 필요한 정보를 제공한다.

    인스턴스를 시작하는 데에 필요한 여러 가지 소프트웨어 환경이 구비되어있는 일종의 템플릿.

    Ubuntu Server 18.04 LTS를 선택했다. 20.04 또한 LTS로, 안정된 버전이기 때문에 상관없지만

    프로젝트 실습으로 우테코 측에서 권장하는 18.04 버전을 선택했다.

     

    3. 인스턴스 유형 선택

    원래 프리 티어 계정을 이용하면 t2.micro만 선택할 수 있지만, 우테코 계정으로는 t2.medium도 선택할 수 있다.

    하지만 아주 조그마한 애플리케이션이고, 단순 실습용이기 때문에 그냥 t2.micro를 선택.

    '검토 및 시작'이 아니고 '다음: 인스턴스 세부 정보 구성' 으로 넘어간다.

     

    4. 인스턴스 세부 정보 구성

    VPC, 서브넷을 선택한 후, 퍼블릭 IP 자동 할당을 활성화시킨다.

    ※ VPC(Virtual Private Cloud) & 서브넷

    AWS 사용자의, AWS 계정 전용 가상 네트워크 환경이다.

    VPC가 없다면 수많은 EC2 인스턴스들이 복잡하게 거미줄처럼 연결되고, 인터넷과 연결되어 복잡도를 증가시킨다.

    그래서 여러 개의 EC2 인스턴스들을 VPC 단위로 묶어 VPC 별로 네트워크를 구성한다.

    그러면 VPC 별로 독립적으로 네트워크 설정을 해줄 수 있다.

    즉, EC2 인스턴스는 VPC의 일부이고, EC2 인스턴스에 접근하기 위해서는 먼저 VPC가 필요하다.

     

    서브넷은 하나의 IP 네트워크를 여러 개의 지역 네트워크로 동작할 수 있게 해준다.

    VPC 내부의 VPC보다 더 작은 단위의 네트워크 환경이라고 생각하면 될 듯.

    VPC가 없을 때
    VPC를 사용할 때

    ※ Public IP vs Private IP

    퍼블릭 IP 주소는 인터넷을 통해 연결할 수 있는 IP 주소를 의미한다.

    퍼블릭 IP 주소는 인스턴스와 인터넷의 상호 통신을 위해 사용된다. 

    또, 퍼블릭 IP 주소가 할당된 각 인스턴스에는 외부 DNS 호스트 이름이 할당된다.

    ex) ec2-203-0-113-25.compute-1.amazonaws.com

     

    프라이빗 IP 주소는 인터넷을 통해 연결할 수 없는 IP 주소를 의미한다.

    대신, 프라이빗 IP 주소는 동일한 VPC 내부에서 인스턴스 간의 통신을 위해 사용된다.

    만약 다른 VPC 간의 통신이 필요하다면, 서로 다른 두 VPC 간에

    트래픽을 라우팅할 수 있도록 하기 위한 두 VPC 간의 네트워킹 연결인 'VPC 피어링 연결' 에 대해서 알아볼 것.

     

    퍼블릭 IP 자동 할당을 활성화 한다는 것은, 외부 IP 에서 해당 인스턴스에 접속할 수 있게 한다는 의미.

     

    5. 스토리지 추가

    인스턴스의 볼륨 크기를 원하는 만큼 설정해주면 된다.

    간단히 말하면, EC2의 디스크 용량을 설정해준다고 생각하면 된다.

    학습용 우테코 계정이기때문에, 기본값으로 설정해주고 바로 넘어갔다.

     

    6. 태그 추가

    여러 개의 EC2 인스턴스들 사이에서 해당 인스턴스를 구분할 수 있게 이름을 붙여준다고 생각하면 된다.

    물론 다른 용도로도 태그를 붙여줄 수 있고.

     

    7. 보안 그룹 구성

    보안 그룹 설정을 통해 EC2 인스턴스로 들어오고 나가는 트래픽에 적용되는 규칙을 제어할 수 있다.

    예를 들어, SSH 접속 포트는 22번으로 지정하고, HTTP 기본 포트는 80번으로 지정하고 이런 식으로.

    우테코 학습용 계정에 기본으로 설정되어있는 보안 그룹을 가져와서 선택해주었다.

    무슨 의미가 있나 싶은 캡쳐

    8. 검토 및 시작(인스턴스 생성 완료)

    이제 인스턴스 설정들을 검토하고, 키 페어를 발급받아 인스턴스를 시작하면 된다.

    여기서 발급받는, 일명 'pem 키(.pem 확장자이므로 붙여진 이름)'는 ssh 접속 시 사용되므로 잘 보관하자.

    재발급이 불가능하다.

     

    RSA와 ED25519는 암호화 알고리즘의 이름. 

    ED25519가 좀 더 강화된 보안 알고리즘이라고 한다.

    그냥 RSA를 선택했다.

     

    9. 인스턴스 연결

    인스턴스를 선택하면 나오는 요약 페이지에서, 우측 상단에 위치한 '연결' 버튼을 클릭해보자.

    그리고나서 'SSH 클라이언트' 탭을 클릭해보면, SSH 에서 어떻게 연결해야하는지에 대한 방법이 전부 나와있다.

    고대로 따라하면 된다.

    대충 Git Bash같은 터미널을 오픈하여 pem 키가 위치한 장소까지 이동한 후에,

    여기서 시키는 대로 다음과 같이 터미널에 입력해준다.

    chmod 400 ${키 이름}.pem
    ssh -i "${키 이름}.pem" ubuntu@${EC2 인스턴스 ID}.ap-northeast-2.compute.amazonaws.com

    처음 접속할 때 'Are you sure you want to continue connecting (yes/no/[fingerprint])?' 이라는 문구가 뜰 텐데,

    처음에 자격을 증명하기 위한 과정이므로 'yes'를 입력한 후에 가볍게 넘어가주면 된다.

     

    ※ chmod(change mode)

    chmod 는 'change mode'의 줄임말. 키 파일에 대한 권한을 변경해주겠다는 의미이다.

    chmod 다음에는 숫자가 세 개 오는데, 순서대로 '나/그룹/전체'에 대한 권한을 의미한다.

    권한은 총 세 가지로, read(4), write(2), execute(1)이다. 이 숫자들의 합으로 권한을 조합할 수 있다.

    예를 들어, read 권한과 write 권한을 둘 다 주고싶다면 4+2로, 6을 주면 된다.

    'chmod 400'은 '나'에게만 'read' 권한을 주겠다는 의미.

    참고: https://hyun0k.tistory.com/entry/Linuxchmod%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC

     

    ※ ssh(Secure Shell)

    ssh는 원격 호스트에 접속하기 위해 필요한 보안 프로토콜이다.

    기존의 원격 접속 방식인 Telnet(텔넷)을 이용하면, WireShark 같은 패킷 분석 프로그램만 사용하더라도

    손쉽게 원격 접속 과정에서 오고가는 비밀번호나 암호화가 필요한 내용들을 가로챌 수 있었다.

    이를 암호화하기 위해 ssh라는 원격 접속 보안 프로토콜이 등장했다.

    클라우드 서비스에서 제공하는 서버는 기본적으로 원격 접속을 통해 접근하고 사용하기 때문에

    ssh의 사용이 필수적이다.

    참고: https://library.gabia.com/contents/infrahosting/9002/

     

    10. 인스턴스 접속 및 세팅

    이제 EC2 인스턴스에 접속된 상태일 것이다.

    우리가 EC2에 올려놓고자 하는 프로젝트를 그대로 clone 해오도록 하자.

    git clone https://github.com/iborymagic/a11y-airline.git

    작업에 필요한 기본 요소들도 함께 설치해주자.

    sudo apt-get update # 패키지 리스트 업데이트
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash # nvm 설치
    . ~/.nvm/nvm.sh # nvm 활성화
    nvm install node # 최신 버전의 node 설치

    apt(advanced package tool)은 Ubuntu에서 사용하는 패키지 관리 시스템.

    패키지를 install, upgrade, clean할 때는 apt-get을 사용한다.

    새로운 패키지를 찾고자 할 때는 apt-cache를 사용한다.

     

    일단 sudo apt-get update를 통해 기존의 패키지들을 업데이트해준다.

    그 다음 nvm을 설치해주고, 활성화 시킨 후에 nvm으로 node를 설치해준다.

     

    만약 Node가 올바르게 설치됐는지, 버젼을 확인하고 싶다면 다음과 같이 입력해볼 것.

    node -e "console.log('Running Node.js ' + process.version)"

     

    11. 프로젝트 빌드

    cd ${프로젝트 폴더} # 프로젝트 폴더로 이동
    node i -g yarn # yarn 패키지 매니저 설치
    # 혹은 curl -o- -L https://yarnpkg.com/install.sh | bash
    
    yarn install # package.json에 명시돼있는 패키지 설치
    yarn build # 빌드

     

    12. 포트 포워딩(Port Forwarding)

    여기까지 진행을 했다면, 아마 서버가 3000번 포트로 열리고 있을 것이다.

    근데 3000번 포트로 열리는 서버의 웹 페이지에 접속하려면, URL의 끝에 항상 ':3000'을 붙여줘야 한다.

    반면, 기본 포트 번호인 80번을 사용하면 끝에 포트 번호를 붙여주지 않고 생략할 수 있다.

    즉, URL 끝에 아무것도 붙이지 않고 웹 페이지에 접근하면 80번 포트로 접근을 한다는 뜻.

    이렇게 80번 포트로 들어오는 접근을 3000번 포트로 보내주기 위해 '포트 포워딩'을 해주는 것.

     

    포트 포워딩을 하는 방법은 크게 nginx를 이용하거나 우분투의 기본 명령어를 사용하는 방법으로 두 가지가 있다.

    여기서는 간단하게 우분투의 기본 명령어를 사용해서 포트 포워딩을 한다.

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

    이제, 포트번호를 붙여주지 않고 웹 페이지에 접근할 수 있게 되었다.

     

     

    13. 서버 실행 및 접속

    이제 서버를 실행해놓으면, EC2 인스턴스 콘솔에 나와있는 '퍼블릭 IPv4 DNS' 를 통해

    내가 배포한 애플리케이션에 접속할 수 있다.

    yarn start

    근데, 여기까지 진행하면 한 가지 문제점을 인지할 수 있을 것이다.

    이런 식으로 열린 서버는 ssh를 종료하는 순간 바로 함께 종료된다.

    그래서 node.js의 프로세스 매니저인 pm2를 활용해서 '무중단 서비스 배포'를 해보자.

     

    14. pm2를 이용한 무중단 서비스 배포

    pm2는 Node.js의 프로세스 매니저이다.

    애플리케이션을 온라인으로 관리하고 유지하는 것에 도움을 준다.

    사용법 또한 간단하기 때문에 이번 무중단 배포에 pm2를 사용해보았다.

    우선, pm2를 global로 설치해준다.

    npm install pm2 -g

    그리고 나서 pm2는 당연히 프로젝트 폴더에 위치한 상태로 실행시켜주면 된다.

    pm2 start yarn -- start

    이렇게 하면 이제 EC2 인스턴스가 켜져있다는 전제 하에,

    ssh를 종료해도 중단되지 않는, 일면 '무중단 서비스 배포'를 완료한 것이다.


    사실 중간중간에 EC2 세부 설정 같은 경우는 기본값으로 그냥 두고 넘어간 것도 많고, 

    아직 완전히 이해를 못한 부분도 꽤나 있다고 생각된다.

    그래도, EC2를 이용한 배포가 뭔가 생각한 것만큼 크게 어렵지는 않구나. 하는 것을 깨닫게 된 계기가 됐다.

    좋은 경험이었다.

    역시 아마존. 아마존 주식 사러 가자.

     

    참고: https://zigsong.github.io/2021/10/02/fe-aws-ec2-next/

    https://mingule.tistory.com/71

    https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/using-instance-addressing.html

    https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/VPC_Subnets.html

    https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html

     

    반응형

    댓글

Designed by Tistory.