[CI/CD] Github Actions 와 Runners 그리고 AWS EC2 linux 으로 React 프로젝트 배포하기

THOVY·2022년 12월 27일
2

PROJECT

목록 보기
18/20

치욕의 젠킨스와 s3, codedeploy, docker hub 같은 것들로 배포가 될 듯 말 듯해 끙끙앓았다.

😡이것 저것 해보며 내린 결론.
EC2 프리티어는 너무 느리고 나약하다.
그들은 나의 프로젝트를 감당할 자질이 없다고 판단, test용으로 방금 만든 따끈따끈한 react 프로젝트를 배포해봤다. 바로 성공.
물론 같은 방법으로 내가 공들여 만들어놓은 프로젝트를 배포했을 땐 브라우저에서 연결시간이 오래걸린다하고, ec2 가 또 먹통이 되었다.

😟

나약한 놈... 그렇게 나약해선 순양을 가질 수 없다.

강해지자!

시작 👊

사용될 도구들 : nodejs 프로젝트, AWS EC2 linux, Github Actions, Github Runners, EC2 에 설치될 docker

전체 플로우는 Actions 에 짜고, Runner 가 EC2 와 연결되어 ghrc 에 있는 docker 파일을 돌릴 거다.

시작해봅시다.

준비물을 준비해놓자.

우리에겐 이제 별거 아니니 빠르게 지나가자

AWS EC2 linux 만드시고,
ec2-user 로 접속해서,
sudo yum update 로 EC2 업데이트하고
sudo yum install docker 로 docker 설치하고
sudo usermod -aG docker $USER 로 docker 를 추가하고
exit 로 껐다가
다시 켜서
docker version 으로 docker 설치 확인하고
sudo systemctl start docker 로 docker 시작시키고
sudo systemctl status docker docker 가 잘 켜졌나 확인하자.

일단 AWS EC2 의 준비는 끝

방금 만들어진 따끈따끈한 우리의 프로젝트는 Dockerfile 도 없겠지

보고 오자 Dockerfile 만들기

이번에도 간단하게 진행해보자
프로젝트 최상위 폴더에 Dockerfile 을 만든다.
.dockerignore 도 만든다.
일단 .dockerignorenode_modules/ 를 추가해놓는다.
Dockerfile 에 들어가는 게 중요하다. 위의 링크에도 있지만,

FROM node:18.10.0
// 나에게 맞는 node 버전을 적어준다.

RUN mkdir -p /app
WORKDIR /app
ADD . /app
// mkdir 로 /app 폴더를 만들어서
// 경로를 /app 으로 이동한 뒤에
// ADD 로 모든 파일을 /app 으로 복사한다

RUN npm install
// yarn 이면 yarn install 하면 되겠지? yarn build 인가?
// 이 명령어가 틀리면 Actions 가 돌아가다 에러가 발생하니 에러가 나면 에러부분을 확인해보면서 고쳐주면 된다.

ENV HOST 0.0.0.0
EXPOSE 3000
// 모든 ip 에서 접근 가능
// 3000 포트 개방 포트 여러개를 개방하려면, EXPOSE 3000 80 이렇게 띄워서 써주면 된다.


CMD ["npm", "start"]
// CMD 는 여러개 적을 수도 있지만 마지막에 작성된 CMD 만 작동한다.
// 컨테이너에서 작동될 명령을 입력한다. yarn 이면 yarn start 를 적어주면 됨

오케. 끝

이제 Github 로 가보자.

Github token 을 만들어서 넣어줘야한다.
우리의 배포 친구들이 우리 github 계정으로 ghcr.io 에 접근해서 docker 이미지를 만들고 build하고 해야하니

  1. setting 으로 간다
  1. 제일 밑에 Developer settings
  1. Personal access tokensTokens(classic)
  1. new token (classic)
  1. 세 개 체크
  1. 만들어주면 감사합니다. 인사하고 애지중지 복사해놓자.
    다시는 볼 수 없는 얼굴이기 때문에 복사해놓고 얼른 우리 repo 의 settings 로 가자

Repository Settings 에 그 token 적어놓기

깔끔한 너구리의 솜사탕처럼 사라질 수도 있기 때문에 조심스럽지만 빠르게
SecretsActions 를 열어 New repository secret 을 열어 붙여넣어준다.
이름은 GHCR_TOKEN 으로 하자. 다른이름으로 해도 상관없고 소문자로써도 대문자가 된다.
Actions workflow yml script 에서 사용할 거기 때문에 귀찮게 왔다갔다 확인하기 싫으면 이름을 생각해놓자.

그대로 Setting 에서 runners 를 보자.

AWS EC2 에 Runners 를 설치해줄 거다.

1.Settings - Actions - Runners

  1. new 눌러서 우리는 EC2 linux 이므로 귀여운 Linux
  1. Download 란의 코드를 차례로 복사해서 EC2 에 입력해 설치해준다. 세번째 Optional 은 안해도 된다.

    매우 재미나게도 복사한 것들은 파랗게 남아있다. 귀엽다
  1. Configure 란의 첫번째를 복사해서 붙여넣으면

    엔터, 엔터, label-superman(예를 든거임) 라고 적고 엔터, 엔터 누르자.
  1. 마지막 ./run.sh 는 하면 바로 끝날 텐데 우리는 백그라운드로 계속 실행시켜놓고 싶으므로
    nohup ./run.sh & 라고 하자

쉴틈 없다. 바로 가자.

바로 Github Actions 로 가서 workflow 를 만들어보자.

  1. Github repo 에서 Actions 을 클릭하고 workflow yourself 로 커스텀해보자.

  2. 코드를 적는다

name: Deploy with Docker
# 내가 만드는 이름이다 뭐든 상관없다

on:
  push:
    branches: [ main ]
    # 무슨 브랜치가 업데이트 될 때 Actions 를 작동시킬지 적는다.
    # develop 브랜치로 개발하며 완료되면 main 에 머지해 Actions 를 작동시키면 조금 더 안전하겠지.
    # 여러개 적어도 된다.

env:
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/chargingpot
  VERSION: ${{ github.sha }}
  NAME: superman
  # Docker image 를 ghcr.io 에 올릴 때 우리의github이름/이미지이름 으로 저장한다. 이미지이름을 정해주면 된다.
  # Docker image 의 이름을 superman 이라고 해놓은 것. 이름 뭐할지 정하면 된다.

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      
      - name: Setup docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
        
      - name: Cache docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ env.VERSION }}
          restore-keys: |
            ${{ runner.os }}-buildx-
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
          # 우리가 방금 복사해서 setting secrets 에 붙여줬던 token 이다. 이름을 기억해 넣어주자.
          # 우리의 ghcr.io 에 접근하기 위함이다.
        
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          builder: ${{ steps.buildx.outputs.name }}
          push: true
          tags: ${{ env.DOCKER_IMAGE }}:latest
  
  deploy:
    needs: build
    name: Deploy
    runs-on: [ self-hosted, label-superman ]
    # label-superman 라는 이름으로 AWS EC2 가 Runner 를 작동시킬 때 사용했던 그 label
    steps:
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
      
      - name: Docker run
        run: |
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
          docker run -d -p 3000:3000 --name superman --restart always ${{ env.DOCKER_IMAGE }}:latest
          
          # 첫 줄
          # 먼저 진행되고 있던 docker 를 stop(멈추고), rm 로 docker 컨테이너를 지우고, rmi 로 docker 이미지를 지운다.
          # 새롭게 build 된 docker 를 사용하기 위함이다.
          
          # 두번째 줄
          # -d : 백그라운드로
          # -p : 포트 번호 3000번에서 3000번으로 접근
          # --name : docker 이미지 이름을 superman 로 할거다. 이게 나중에 위에 적은거랑 같아야하는데 왜냐면 첫 줄이랑 같아야 나중에 지워지니까. 확인하자.

yml 이 완성되면 commit 하자. 알아서 Actions 가 돌아가며

이렇게 완성될거다.

완성되면 우린 바로 접속해볼 수 있다. EC2 IP:3000 에 접속하면

따란~

물론 프로젝트가 무겁다면 곧바로

이GR하다가 뻗어버릴 수도 있다.

나약한 놈.

하지만

지금 우리가 만든 workflow 와 ec2 는 우리가 main 브랜치가 업데이트 할 때마다 새롭게 돌아가며 docker 이미지를 지우고 새롭게 만들어 다시 만들어 줄거다.
천천히 프로젝트를 완성시켜가보자.

하지만

내가 공들여 만들어 놓은 프로젝트를 배포할 수 없다면 이 방법 또한 뭔가 문제가 있는 거지.

EC2 가 나약하다면 미래의 순양을 이어갈 다른 자식을 찾아내자.

새로운 방법을 끝까지 찾아내서 배포해버리고 만다.

🙂? ㅎㅎ

다음달에 하자...ㅎ

안녕 2022년

profile
BEAT A SHOTGUN

1개의 댓글

comment-user-thumbnail
2023년 1월 29일

안녕하세요!
글 아주 친절해서 너무 편하게 잘 봤습니다.
궁금한게 있는데요.
마지막 yml 파일에서 build and push 쪽에서

Error: buildx failed with: ERROR: failed to solve: failed to read dockerfile: open /tmp/buildkit-mount892762416/Dockerfile: no such file or directory

이런 에러가 나오거든여.
도커 파일을 못찾는것 같은데 builder의 ${{ steps.buildx.outputs.name }} 여기에 따로 어떤 값을 넣어야 하나요..?

답글 달기