티스토리 뷰

devops

github action으로 ec2에 자동배포하기3

안양사람 2021. 10. 18. 23:09
728x90
SMALL

https://ms3864.tistory.com/381

 

github action으로 ec2에 자동배포하기1

우아한테크캠프 마지막 프로젝트 때 나는 자동배포부분을 맡지 않아서 꼭 혼자서 다시 해보고 싶었다. 그리고 삽집도 많이했는데 다시 삽질하지 않겠다는 의지(?)를 갖고 블로그에 글을 정리한

ms3864.tistory.com

https://ms3864.tistory.com/382

 

github action으로 ec2에 자동배포하기2

지난 글에서는 깃헙액션, 워크플로우에 대해 알아보았다. 이번에는 aws 관련 설정들을 알아보겠다. 그전에 먼저 대략적인 흐름을 설명하겠다. 원래 배포를 할때는 ec2를 생성하고 기본 우분투 설

ms3864.tistory.com

 

서론은 생략하겠다

7. 키 등록

이제 받은 Access key ID, Secret access key를 github settings-secrets에서 추가해줘야 한다. 첫번째 글에서 봤겠지만 yml파일에 변수로 넣을 것이다.

 

8. EC2에서 aws에 로그인

# 설치
$ sudo apt update
$ sudo apt install awscli
# 설치 확인
$ aws help
# 사용자 설정
$ aws configure
AWS Access Key ID [None]: 액세스 키를 입력
AWS Secret Access Key [None]: 시크릿 액세스 키를 입력
Default region name [None]: ap-northeast-2 # 혹시 리전이 다르면 해당 리전 기입
Default output format [None]: 그냥 Enter 입력

 

9. 워크플로우 설정

이제 다시 첫번째 글의 내용을 생각해보자. 우리가 지금 하는 것은 깃헙 액션으로 자동배포를 하기 위해서다. 그리고 자동배포 워크플로우를 만들고 있엇다. 그때 설명할 수 없었던 것들을 이제 설명할 수 있게 되엇다..

 

먼저 env파일을 넣어주자. secrets로 변수에 접근할 수 있다.

아래 사진을 참조해주세요. 댓글에서 질문이 있어서 추가했어요

      - name: create env file
        working-directory: ./server
        run: |
          touch .env
          cat << EOF >> .env
          ${{ secrets.ENV }}

 

여기서 조금 특이한 점이라면 build먼저 하고 그 내용을 압축해서 올리는 것이다. aws서버에서 직접 yarn install을 하면 부하가 걸려서 멈출수도 있다. 실제로 그런 경우가 많이 있었다. 나는 프론트쪽만 웹팩으로 build해서 올렸는데 서버도 그렇게 할 수 있다. 이부분은 조금 더 생각해보고 생각이 바뀐다면 글을 추가하겠다.

      - name: build client files
        working-directory: ./client
        run: |
          yarn install
          yarn build

      - name: zip distributions
        run: zip -r blog-vanilla.zip ./client/dist ./server ./appspec.yml ./scripts

 

aws를 인증하고  s3에 업로드를 한다. 이때 지역, 올릴 zip 이름, s3저장소 경로를 적어주면 된다.

마지막으로 codeDeploy를 이용해 배포하는 것이다.

application-name에는 아까 만든 codeDeploy 어플리케이션 이름을 입력하고

deployment-config-name에는 아까 입력한 옵션 OneAtTime을 적어준다.

그리고 group-name에도 아까 만든 그룹 이름을 적어줘야 한다.

s3-location의 bucket에는 아까만든 버킷이름(위의 s3 upload경로의 앞과 같다.)

key는 위의 upload to S3를 참고해서 적어주면 된다.

      - name: AWS configure credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - name: upload to S3
        run: aws s3 cp --region ap-northeast-2 ./blog-vanilla.zip s3://blog-vanilla-bucket/public/

      - name: deploy with AWS codeDeploy
        run: aws deploy create-deployment
          --application-name blog-vanilla-codedeploy
          --deployment-config-name CodeDeployDefault.OneAtATime
          --deployment-group-name deploy-group
          --s3-location bucket=blog-vanilla-bucket,bundleType=zip,key=public/blog-vanilla.zip

 

10. 진짜 배포하기(appspec.yml)

사실 아직 배포한게 아니다. s3에 파일을 올린 것이다. 이제 배포를 해보자

appspec.yml파일을 만들어서 진행한다.

 

version은 지금 유일하게 허용되는건 0.0이다.(2021.10.18 기준)

destination에는 말그대로 그곳에 파일을 올려준다.

permission은 이 섹션에서는 배포의 설치 이벤트 중 인스턴스에 복사해야 하는 파일의 이름을 지정한다.

hooks 이 섹션은 배포를 확인하기 위해 특정 배포 수명 주기 이벤트 후크에서 실행할 Lambda 함수를 지정한다.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/blog-vanilla
    overwrite: yes

permissions:
  - object: /home/ubuntu
    pattern: '**'
    owner: ubuntu
    group: ubuntu

hooks:
  AfterInstall:
    - location: scripts/after-deploy.sh
      timeout: 180
      runas: ubuntu

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file.html

 

CodeDeploy pec 파일 참조 - AWS CodeDeploy

tar 및 압축 tar 아카이브 파일 형식 (.tar 및 .tar.gz) 은 Windows Server 인스턴스에서 지원되지 않습니다.

docs.aws.amazon.com

 

hooks를 살펴보자

그전에 codeDeploy이벤트를 보면 당므과 같다. 여기서 여러가지 훅스를 사용할 수 있다. 나는 afterinstall 훅스를 사용했다. 이벤트의 자세한 내용은 아래 링크에 들어가면 있다. timeout은 지정한 초를 넘어가면 배포를 멈춘다.

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-server

 

AppSpec '섹션 - AWS CodeDeploy

배포의 Start, DownloadBundle, Install, BlockTraffic, AllowTraffic 및 End 이벤트는 스크립팅할 수 없기 때문에 이 다이어그램에서 회색으로 표시됩니다. 그러나 AppSpec 파일의 'files' 섹션을 편집하여 이 중 설치

docs.aws.amazon.com

 

after-deploy.sh

#!/bin/bash
REPOSITORY=/home/ubuntu/blog-vanilla

cd $REPOSITORY
sudo cp -r dist/* /var/www/html/
sudo service nginx restart

cd $REPOSITORY
cd server
yarn install
pm2 kill
yarn prod

여기는 유동적으로 코드를 작성하면 된다. 사실 복사해서 nginx파일을 옮기는 것도 어떻게 보면 불필요하다. pm2 kill은 뭐가 좀 지금 안되서 그러는데 보통은 클러스터링모드로 키고 pm2 reload --name으로 무중단 배포를 할 수 있다. nginx는 무중단 배포를 아직 공부하지 않아서 잘 모르겠다.

-- 추가

nginx는 restart를 하지 않아도 괜찮다. nginx 설정을 바꿀때만 해주면 된다. 그리고 편의상 nginx root 설정을 home/ubuntu/~~/client/dist로 바꾸고 클라이언트쪽 코드를 제거했다.다시 해보니 reload가 정상적으로 작동해서 처음에만 yarn prod를 실행하고 그다음은 reload를 사용하면 된다.

 

pm2랑 typescript가 잘 실행이 안되서 삽질을 많이 했다.

먼저 우분투에서 yarn global add pm2, pm2 install typescript으로 설치를 하자그리고 서버 pacakge.json에

  "scripts": {
    "build": "tsc",
    "dev": "cross-env NODE_ENV=development tsc-watch --onSuccess \"ts-node --files -r tsconfig-paths/register dist/app.js\" ",
    "prod": "tsc && cross-env NODE_ENV=production pm2 start --name api ts-node -- --files -r tsconfig-paths/register dist/app.js - i max",
    "lint": "eslint src --ext .ts --parser-options=project:'tsconfig.json'",
    "lint:fix": "eslint src --ext .ts --parser-options=project:'tsconfig.json' --fix"
  },

여기서 prod로 실행하고 pm2 reload api를 입력하면 서버 무중단 배포 완료~~(프로세스가 한개라면 안된다...)

 

메모리 부족 이슈

https://github.com/woowa-techcamp-2021/store-10/wiki/ec2-%EC%9A%A9%EB%9F%89%EC%9D%B4-%EC%99%A4%EC%BC%80-%EB%A7%8E%EC%9D%B4-%EC%B0%A8%EC%A7%80%ED%95%98%EB%8A%94%EC%A7%80-%EC%9B%90%EC%9D%B8-%EB%B6%84%EC%84%9D-%EB%B0%8F-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95

 

기타..

깃헙 액션에서는 배포가 잘 되는데 codeDeploy에서 오류가 나는 경우가 있었다. 그런 경우는 이벤트를 들어가서 보면 된다. 나는 after deploy에서 오류가 많이 났었다. 또 배포가 성공해도 그게 설정이 잘못되면 다음 배포가 성공하지 못한다고 한다...(이게 말이돼??)

aws deploy create-deployment --application-name blog-vanilla-codedeploy --deployment-group-name deploy-group --ignore-application-stop-failures --s3-location bucket=blog-vanilla-bucket,bundleType=tar,key=KEY --description "Ignore ApplicationStop failures due to broken script"

그럴때 이렇게 수동으로 이전 단계(ApplicationStop)를 무시하는 코드를 입력해줘야한다.

728x90
LIST
댓글
공지사항