Github Action, Docker 통한 EC2 자동배포

Featured image

프로젝트에서 cd역할을 맡아 Github Action을 사용한 docker를 사용해 ec2자동 배포를 하려고 한다

깃허브 액

션 깃허브 액션이란 깃허브에서 제공하는 CI/CD 파이프라인 자동화 플랫폼 깃허브 액션은 2022년 개인 사용자가 가장 선호하는 툴로 선정 기업은 젠킨스 선택

깃허브 액션의 특징

  1. 깃허브 레포지토리 기능과 완전 통합 레포지토리 내 특정 디렉토리에 YAML 파일로 작성하는 쉬운 구성

  2. 유연하고 강함 간단한 작업부터 복잡한 작업까지 가능

  3. 다양한 플랫폼과 환경지원

  4. 마켓플레이스-> 다른 사용자가 구현한 기능의 워크플로우 공유가능

5.CI Template 지원: 배포 과정이 이미 구성되어 있는 다양한 종류 템플릿 제공

  1. 무료 빌드 지원 2000 시간

깃허브 액션 작동 단계

  1. yaml로 깃허브 액션 코드 작성
  2. 워크플로 실행
  3. 실행기에서 정의된 작업 수행

깃허브 활용

cl/cd, 테스트 자동화 코드 협업 관련 자동화

깃허브 액션 기본 구성

디렉토리내 파일 별도의 설정과정없이 그대로 액션탭 통해 실행가능

특정 이벤트가 일어난 것을 감지 후 실행

1) 깃허브의 레포지토리에서 일어나는 작업(push, fork) 2) 깃허브 프로젝트, 이슈에서 일어나는 작업 3) 사용자가 직접 트리거 지정

작업(job): 워크플로우 내 작동하는 작업 단위 작업기(Runner): 작업별 별도의 공간에서 실행 작업공간에 대한 정의 스텝(step): job내 개별 수행되는 액션 정의 작업간 내용 공유 제공X

작동 순서

전제조건:깃허브 레포지토리의 메인에 푸시가 될때

  1. 워크플로우가 실행되는 러너의 파일 시스템에 현재 리포지토리의 코드를 복사
  2. 도커허브에 로그인
  3. 현재 도커파일과 env파일을 사용해 도커 이미지 빌드
  4. 빌드한 이미지 도커허브에 push
  5. pem키를 사용해 ec2에 접속
  6. ec2 레포지토리에 도커허브에서 pull받기
  7. 도커 런
  8. 사용하지 않는 컨테이너 지우기

설정

  1. 도커 레포지토리만들기 도커허브의 회원가입 후 로그인-> 레포지토리 만들기

이때 사용했던 유저이름, 비밀번호 기억하기(나중에 깃액션에서 사용)

  1. Ec2인스턴스에 도커 설치하기 필요한 패키지 설치: ``` bash sudo apt-get update sudo apt-get install
    apt-transport-https
    ca-certificates
    curl
    software-properties-common
Docker의 공식 GPG 키 추가
``` bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Docker 리포지토리 추가

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

Docker CE 설치

sudo apt-get update
sudo apt-get install docker-ce

Docker 설치 확인

docker --version

사용자에 도커 권한주기 참고

sudo groupadd docker
sudo usermod -aG docker $USER
sudo newgrp docker

한줄씩 치고 ec2나갔다가 다시 들어오기

깃허브 시크릿

시크릿에 저장해야 할것 정리

  1. DATABASE_HOST
  2. DATABASE_NAME
  3. DATABASE_PASSWORD
  4. DATABASE_PORT
  5. DATABASE_URL
  6. DATABASE_USERNAME
  7. PORT
  8. JWT_SECRET .env파일에서 쓰는 값들 -> 도커 이미지를 만들어 push할때 사용!

9.DOCKER_REPO: 저장할 도커레포지토리 자신의 도커 허브 닉네임으로 하기

레포지토리 만들때 아마 자기 이름이 앞에 들어가고 뒤에 만든 이름 들어감 soi/trello 이렇게

  1. DOCKER_TOKEN: 이름은 토큰이지만 도커 비밀번호 들어감
  2. DOCKER_USERNAME: 도커허브의 유저 네임
  3. EC2_HOST: ec2의 퍼블릭 ip 주소
  4. EC2_USERNAME: 인스턴스에서 whoami치면 알 수 있음 ubuntu의 기본값 ubuntu
  5. REMOTE_PRIVATE_KEY: pem 파일의 값 aws의 ec2들어가서 왼쪽 보면 키페어 존재

키페어 들어가면 작업 누르면 키페어 가져오기 있음 여기가서 자기한테 있는 키페어 선택하면 값이 보임 처음부터 끝까지 전부 넣어야 함

도커 파일

각 명령어의 의미는 [이미지 명령어 정리] (https://velog.io/@soijeongg/Dockerfile-%EC%9D%B4%EB%AF%B8%EC%A7%80%EB%A7%8C%EB%93%A4%EA%B8%B0) 참고

# 부모 이미지 지정
FROM node:20.11.1
# app 디렉토리 생성

# ARG로 빌드 시점 변수를 선언
ARG DATABASE_URL
ARG PORT
ARG DATABASE_HOST
ARG DATABASE_PORT
ARG DATABASE_NAME
ARG DATABASE_USERNAME
ARG DATABASE_PASSWORD
ARG JWT_SECRET
# ENV로 런타임 환경 변수를 설정
ENV DATABASE_URL=$DATABASE_URL \
    PORT=$PORT \
    DATABASE_HOST=$DATABASE_HOST \
    DATABASE_PORT=$DATABASE_PORT \
    DATABASE_NAME=$DATABASE_NAME \
    DATABASE_USERNAME=$DATABASE_USERNAME \
    DATABASE_PASSWORD=$DATABASE_PASSWORD \
    JWT_SECRET=$JWT_SECRET

LABEL creator="no6@trello"
LABEL version="1.0.0"



#Docker 이미지 내부에서 RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정합니다.

WORKDIR /app

# 외부 패키지 설치를 위해 package.json과 yarn.lock 파일 복사
COPY package.json .
COPY yarn.lock .

# 패키지 설치
RUN  yarn install

# 나머지 모두 복사
COPY . .
# 현재 디렉터리에 있는 파일들을 이미지 내부 /app 디렉터리에 추가함

ADD     . /app
RUN yarn prisma generate
# 하기 포트를 외부로 노출합니다.


CMD [ "yarn","dev" ]

git action 파일

name: Deploy to EC2

on:
  push:
    branches: //브런치 설정
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2   //체크아웃

      - name: Log in to Docker Hub
        uses: docker/login-action@v2   //도커허브 로그인
        with:
          username: $
          password: $
      - name: Build and push Docker image
        run: |
          docker build \
            --build-arg DATABASE_URL=$ \
            --build-arg PORT=$ \
            --build-arg DATABASE_HOST=$ \
            --build-arg DATABASE_PORT=$ \
            --build-arg DATABASE_NAME=$ \
            --build-arg DATABASE_USERNAME=$ \
            --build-arg DATABASE_PASSWORD=$ \
            --build-arg JWT_SECRET=$ \
            -t $/trello .
          docker push $/trello

      - name: SSH into EC2 instance and restart Docker container
        uses: appleboy/ssh-action@master  //깃액션에서 ssh통해 원격서버에 명령

        with:
          key: $
          host: $
          username: $

          port: 22
          script: |
            sudo  docker stop trello
            sudo docker rm trello
            sudo docker pull $/trello
            docker run -d --name trello -p 3000:3000  --env-file .env $/trello
            docker system prune -a

에러

혹시 아무 문제 없는데 ssh에 timeout이 뜬다

인스턴스 보고 cpu확인-> 너무 많이 차면 그냥 버리고 새로 만들어야 함

ec2인증실패-> 호스트 아이피, rsa키 맞는지

순서가 키, 호스트, 유저네임인지 확인

참고

https://github.com/occidere/TIL/issues/116

https://haengsin.tistory.com/128