배포자동화

아침7시개발·2022년 9월 30일
0

CI/CD

목록 보기
1/3

배포자동화

배포자동화 유튜브를 따라해 보자.
1. 로컬 PC에서 개발을 한 후 Github에 Push를 한다.
2. Github Repository 특정 branch에 push가 되면 Github Action이 동작을 시작한다.
3. Github Actions가 Github Container Registry에 소스를 받은 후 Docker 이미지로 빌드를 한다.
4. 빌드된 이미지를 EC2에 등록된 Runner가 복사한다.
5. 기존 이미지를 삭제하고 새로운 이미지로 실행을 한다.

git hub

git hub에 push 하기 위해서 먼저 설정할 것들이 있다.

  1. Repository name은 프로젝트명과 동일하게 생성한다.
  2. Repository는 아무나 사용할 수 없도록 private으로 만든다.
  3. 주의할 점은 Owner명에 대문자가 들어가 있으면 안된다.
  4. Github Action에서 도커빌드시에 대문자를 쓸 수 없다는 오류가 난다.

project

깃헙에 리포지토리를 생성했다면 clone을 받고 프로젝트를 생성한다.
프로젝트는 nuxt로 한다.

npx create-nuxt-app auto-deploy .

선택항목은 엔터만 눌러서 전부 디폴트 선택을 한다.

npm run dev 또는 yarn dev

필자는 node 버전을 너무 높게 해서 에러가 났었다. node 버전은 lts로 설정해서 진행하도록 한다.

Dockerfile

도커파일을 루트 폴더에 생성한다.

FROM node:16.17.1 # 이미지를 받아서 docker image를 생성한다.

RUN mkdir -p /app # app 폴더를 생성한다.
WORKDIR /app
ADD . /app/ # 현재 폴더의 모든것을 생성된 app 폴더에 복사한다.

RUN rm yarn.lock || true파일 삭제. 뒤의 "|| true" 는 파일이 없을 경우 오류로 인해 실행이 중단되지 않게 하기 위해 추가한다.
RUN rm package-lock.json || true
RUN yarn
RUN yarn build #  nuxt 프로젝트를 빌드

ENV HOST 0.0.0.0 # 모든 IP를 개방
EXPOSE 3000 # 3000번 포트를 개방

CMD [ "yarn", "start"] # yarn start 명령

.dockerignore

도커 이미지 생성할 때 불필요한 파일 제외할 수 있게 루트 폴더에 생성한다.

node_modules/
dist/

dockerfile test

  1. docker 이미지 생성
docker build -t auto-deploy:0.0.1 .
  1. doker 이미지 실행
docker run --name auto-deploy -d -p 3000:3000 auto-deploy:0.0.1
  1. 프로젝트 확인
    localhost:3000로 접속해서 확인한다.

git hub action

1. Github Access Token 발급 && Secret 등록
Github Access Token은 Packages의 권한을 가진다.
Github Container Registry로 docker image를 배포하고 EC2(runner) 실행 할 때 docker login에 사용된다.

Github 계정의 Settings -> Developer settings -> Personal access tokens에서 새로운 token을 만든다.

위 사진처럼 4개의 scopes를 선택해주고 생성한 뒤에 생성된 토큰을 복사해 Repository의 secret에 등록해서 사용한다.(실제 계정 토큰이므로 노출되어서는 안됨)

Repository의 Settings -> Secrets -> Actions -> new repository secret을 눌러 만든다.
name은 gchr_token으로 한다.
action에서 사용할 workflows의 yml에 gchr_token으로 설정할 예정이다.


요기서 Feature preview를 눌러서 Enable을 눌러줘야 build and push가 가능하다고 한다.

Workflow 작성

Repository의 Actions 탭에서 set up a workflow yourself 버튼을 눌러 yml 파일을 작성한다.

name: CI/CD Docker

# 트리거를 수행할 브랜치를 지정합니다.
on:
  push: # master 브랜치에 push or 병합 될 때만 실행되도록 설정
    branches: [ master ] # 내가 사용하는 브랜치명으로 한다.

# 환경설정
env: # Docker image 이름과 version, name을 미리 환경변수로 지정
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/auto-deploy #나의 리포지토리명
  VERSION: ${{ github.sha }}
  NAME: go_cicd

jobs: # build와 deploy라는 job을 생성
  # 빌드 Job
  build:
    name: Build
    runs-on: ubuntu-latest # runs-on은 어떤 OS에서 실행될지를 지정
    steps: 
      # github repository에서 checkout
      - uses: actions/checkout@v2
      # docker build 수행
      # github repository에서 가상의 컨테이너 안으로 checkout
      - name: Set up docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
      # github repository에서 가상의 컨테이너 안으로 checkout
      - name: Cache docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ env.VERSION }}
          restore-keys: |
            ${{ runner.os }}-buildx-
      # GitHub 컨테이너 레지스트리에 로그인 후 빌드 & 푸시
      # 가상의 컨테이너 안에 docker가 돌아갈 수 있는 환경을 설치
      # 생성한 토큰을 이용해 GHCR에 로그인
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
      - 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
  # 배포 Job
  # GHCR로 Docker image를 만들고 push
  deploy:
    needs: build  # build 후에 실행되도록 정의
    name: Deploy # Deploy는 GHCR에 로그인 후 저장되어 있는 Docker image를 이용해 컨테이너를 실행
    # runs-on 중 self-hosted는 필수로 써야한다.(이 값을 설정해야 서버에 등록한 runner가 실행된다.)
    runs-on: [ self-hosted, label-go ] # AWS ./configure에서 사용할 label명
    steps:
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
      # 3000 -> 80 포트로 수행하도록 지정
      - name: Docker run
        run: |
        # Docker run은 실행 중인 도커 컨테이너를 중지하고 이전 버전인 컨테이너와 이미지를 삭제 후 새로운 이미지로 컨테이너를 run
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
          docker run -d -p 80:3000 --name go_cicd --restart always ${{ env.DOCKER_IMAGE }}:latest

Runner 설정

  1. aws console에 로그인한다.

  2. ec2 dashboard 페이지로 이동한다.

  3. 사용할 인스턴스의 체크박스를 체크하고 연결 버튼을 누른다.

  4. SSH 클라이언트 탭을 클릭하고 예에 써있는 것을 카피한다.

  5. 자신의 pem키가 있는 곳에서 cmd창을 열고 ssh -i "공개 키" 퍼블릭 dns 를 입력한다.

  6. 자신의 ec2에 접속을 확인한다.

  7. git hub에서 Repository의 Settings -> Actions -> Runners로 가서 New self-hosted runner를 누른다.

  8. 위의 사진의 빨간 네모 안의 명령어를 ec2에 입력한다.
    첫 번째에 대한 답은 복수개의 runner를 등록할 때 github 상에서 구분할 수 있는 runner의 이름을 지정하면 된다.
    두 번째에 대한 답은 실행되는 runner를 구분하기 위한 것이므로 yml 파일의 Deploy에서 runs-on에 설정해주었던 label-go를 입력하면 된다.
    -> 둘 다 임의로 변경 가능
    이렇게 설정한 이름은 Repository의 Settings -> Actions에서 확인할 수 있다.

마지막으로 ./run.sh를 실행하면

./run.sh은 다른 작업을 하지 못하므로 nohup ./run.sh &를 이용해 백그라운드로 runner를 실행시킨다.
이제 서버에서는 Job을 Listening하고 지정한 branch에 push가 되면 자동으로 EC2에 이미지가 실행되고 자동으로 배포된다.

참조

soosungp33.log
배포자동화 유튜브

profile
쉬엄쉬엄하는 개발자

0개의 댓글