오픈소스SW

오픈소스SW_Github Actions

강용민 2023. 1. 21. 01:15

Django 프로젝트를 하면서 CD를 위해 Github Actions를 사용하기로 해 전 프로젝트에서 한번도 사용해본적이 없기에 공부할 겸 포스팅했다.

Github Actions란?

GitHub Actioins는 GitHub에서 제공하는 CI(Continuous Integration)/CD(Continuous Deployment)를 위한 서비스이다.
GitHub Actions를 사용하면 Github repository에 어떤 이벤트가 발생했을 때 특정 작업이 일어나게 하거나 주기적으로 어떤 작업들을 반복해서 실행시킬 수도 있다. 즉, 특정 이벤트의 루틴을 만들어주는 것이다. 예를 들어 어떤 repository에 PR(Pull Request)를 생성하게 되면 Github Actions를 통해 해당 코드 테스트를 진행한다거나 AWS나 GCP등 클라우드 서버에 자동으로 배포하게 할 수 있다.

GitHub Actions의 구성요소

GitHub Actions의 구성요소는 위 그림과 같다. 하나의 이벤트는 하나 이상의 작업을 포함하고 있고 하나의 작업은 하나 이상의 단계로 이뤄져 있다.

 

workflows

workflow는 하나 이상의 작업을 실행 하는 프로세스이다. workflow는 리포지토리 디렉터리에 정의되며, .github/workflows 리포지토리에 저장한다.

 

Events

Event는 워크플로우를 실행시키는 특정 활동이다. 예를 들어 누군가 PR 생성한다거나 커밋을 푸시할 때 활동등을 하는 것들이 있다.추가적인 이벤트들은 Github Docs에서 확인할 수 있다.

 

Jobs

Job은 workflow의 일련의 단계다.각 단계는 동일한 Runner에서 실행되므로 한 단계에서 다른 단계로 데이터를 공유할 수 있다. 또한 다른 작업과 작업의 종속성을 구성할 수 있다.작업이 다른 작업에 종속되면 종속 작업이 완료될 때까지 기다린다.

 

Runner

Runner는 트리거될 때 workflow를 실행하는 서버이다. 각 러너는 한 번에 하나의 작업을 실행할 수 있다.

 

Github Acion 설정

대략적으로 github actions를 알아봤으니 실습해보자. 실습은 Django 프로젝트기반으로 만들었다.

Github Secrets 설정

해당 프로젝트의 백엔드 부분에서 MySQL RDS 설정부분과 Django_Secret_Key를 .env파일에 저장했다. 이 파일은 Github에 올라가지 않기에 Actions secrets에 따로 설정해줘야 한다.
Actions Secrets 경로는 다음과 같다. settings -> Secrets and variables -> Actions

Repository secrets를 보면 3개의 정보가 들어간것을 볼 수 있는데 각각의 정보는 다음과 같다.

  • ENV_VARS : .env 정보
  • HOST : 배포할 EC2서버의 public DNS(IPv4) 주소
  • KEY : 배포할 EC2 서버로 접근 가능한 ssh key(.pem등)
    • cat pem경로를 통해 pem 파일 내용을 확인할 수 있는데 ----BEGIN RSA PRIVATE KEY----부터 ----END RSA PRIVATE KEY----까지 모든 내용을 복사해야 한다. 단 끝의 %는 포함되면 안된다.

Workflow 설정

name: Deploy to EC2

# develop 브랜치에 push 이밴트가 발생했을 때 job을 실행한다.
on: 
  push:
    branches: [develop]

# job들의 설정은 다음과 같다.
jobs:
  # build라는 job울 살행한다.
  build:
    name: Build
    # ubuntu OS에서 실행된다.
    runs-on: ubuntu-latest
    # step들은 다음과 같다.
    steps:
    # chekcout이라는 step을 실행한다.
    - name: checkout
      # actions의 checkout이라는 레포지토리의 Action을 사용한다.
      uses: actions/checkout@master


    - name: create env file
      # 다음 명령어를 실행한다.
      run: |
        # Github Secretes에서 설정한 ENV_VARS라는 값을 .env파일에 저장한다.
        touch .env
        echo "${{ secrets.ENV_VARS }}" >> .env

    - name: create remote directory
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ubuntu
        key: ${{ secrets.KEY }}
        script: mkdir -p /home/ubuntu/srv/ubuntu

    - name: copy source via ssh key
      uses: burnett01/rsync-deployments@4.1
      with:
        switches: -avzr --delete
        remote_path: /home/ubuntu/srv/ubuntu/
        remote_host: ${{ secrets.HOST }}
        remote_user: ubuntu
        remote_key: ${{ secrets.KEY }}

    - name: executing remote ssh commands using password
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ubuntu
        key: ${{ secrets.KEY }}
        script: |
          sh /home/ubuntu/srv/ubuntu/deploy.sh

다 설정이 끝났다면 workflow에 설정한데로 develop 브랜치에 push해보자.
다음과 같이 뜨면 성공이다.

 

Error

프로젝트를 하면서 만났던 오류들을 봐보자.

[Errno 28] No space left on device

클라우드 서버에 용량이 부족해서 생기는 현상이다. 클라우드 서버 용량을 늘리거나 기존 파일을 좀 정리하자.

err: Cannot locate specified Dockerfile: Dockerfile

해당 프로젝트에서 submodule을 사용했는데, action시 클라우드 서버에 올라가는 리포지토리는 Docker 리포지토리뿐이라 submodule의 init&update 가 필요하다.

sudo git submodule init
sudo git submodule update --recursive --remote --merge

이 명령어는 프로젝트 deploy.sh 에 설정되어 있으며, deploy.sh 실행은 workflow 파일 마지막 step에서 이뤄진다.

 

[참고]
https://github.com/hanqyu/django-docker
GitHub Docs