오늘은 캡스톤디자인2(AllerCheck) 프로젝트에서 CI/CD를 구축하기 위해 Github Actions를 도입하였는데요. 이 과정에 대해 상세히 포스팅해보려고 합니다.
우선 Github Actions, CI/CD가 무엇인지 간략한 정리와 함께 Github Actions에서 사용하는 개념도 함께 정리해 보도록 하겠습니다.
Github Actions
- 소프트웨어 개발 워크플로우를 자동화하는 도구, 이를 통해 빌드, 테스트, 배포 등의 작업을 자동화하고, 프로젝트의 생산성과 효율성을 향상시킬 수 있습니다.
- 워크플로우는 Github 저장소에서 직접 관리되며, 이벤트에 따라 자동으로 실행됩니다. 예를 들어 푸쉬나 풀 리퀘스트와 같은 Github Event에 의해 트리거 되거나, 스케줄에 따라 실행되도록 설정할 수 있습니다.
- 코드 저장소(Repository)로 유명한 깃허브(Github)에서 제공하는 CI(Continuous Integration)와 CD(Continuous Deployment)를 위한 비교적 최근에 추가된 서비스입니다. 당연히 Github에서 코드를 관리하고 있는 소프트웨어 프로젝트에서 사용할 수 있으며 개인은 누구나 Github에서 코드 저장소를 무료로 만들 수 있기 때문에 다른 CI/CD 서비스 대비 진입장벽이 낮은 편입니다.
- Github actions을 사용하면 자동으로 코드 저장소에서 어떤 이벤트(event)가 발생했을 때 특정 작업이 일어나게 하거나 주기적으로 어떤 작업들을 반복해서 실행시킬 수도 있습니다. 예를 들어 누군가가 코드 저장소에 Pull Request를 생성하게 되면 Github Actions를 통해 해당 코드 변경 부분에 문제가 없는지 각종 검사를 진행할 수 있습니다.
- 어떤 새로운 코드가 기본 브랜치(master 또는 main)에 유입(push)되면 Github Actions 통해 소프트웨어를 빌드(build)하고 상용 서버에 배포(deploy)할 수도 있습니다.
- 이렇게 소프트웨어 프로젝트에서 지속적으로 수행해야하는 반복 작업들을 업계에서는 소위 CI/CD라고 많이 줄여서 부릅니다. 사람이 매번 직접 하기에는 비효율적인 데다가 실수할 위험도 있기 때문에 자동화시키는 것이 유리합니다.
- Github Actions는 기존 CI/CD 서비스 대비 간편한 설정과 높은 접근성을 가지고 있습니다.
CI(Continuous Intergration)/CD(Continuous Deployment)
CI(Continuous Intergration)
- 지속적인 빌드와 테스트 자동화를 뜻합니다.
- 개발자들이 자신의 코드 변경사항을 공유 저장소에 병합하는 것을 뜻합니다.
- 일반적으로 이 프로세스는 모든 변경사항에 대해 자동화된 빌드와 테스트를 수행하여 버그를 조기에 발견하고 해결합니다.
CD(Continuous Deployment)
- 개발자의 변경 사항을 리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리즈하는 것을 의미합니다.
- 애플리케이션 제공 속도를 저해하는 수동 프로세스로 인한 운영팀의 프로세스 과부하 문제를 해결합니다.
- 지속적인 배포는 다음 단계를 자동화함으로써 지속적인 서비스 제공의 장점을 활용할 수 있습니다.
Release
- Deploy (배포)는 소프트웨어를 하나의 환경에서 다른 환경으로 옮기는 것과 관련이 있습니다. 일반적으로 ‘환경’의 예로는 개발, 테스트, 스테이징, 프로덕션 환경이 있다. 기본적인 테스트가 완료된 서비스를 실제 데이터로 구현해 보기 위해 스테이징 환경으로 배포하는 것이 좋은 예가 될 수 있습니다.
- Release (출시)는 서비스나 기능을 사용자가 사용 할 수 있게끔 만드는 것이다. 앱 스토어에 새로운 앱이 출시되거나 업데이트 버전이 올라오는 것을 출시로 볼 수 있습니다.
- Release는 소프트웨어의 새로운 버전을 만들고 공개하는 단계이고, Deploy는 그러한 release를 실제 프로덕션 환경에 설치하고 실행하는 단계를 나타냅니다.
이제 Github Actions의 개념과 CI/CD에 대해 알아보았으니, Github Actions에서 내부적으로 사용하는 개념들에 대해 하나씩 알아보겠습니다.
Workflows
- Github Actions에서 가장 상위 개념인 워크플로우(Workflow, 작업 흐름)는 쉽게 말해 자동화해 놓은 작업 과정입니다.
- 워크플로우는 코드 저장소 내에서 .github/workflows 폴더 아래에 위치한 YAML 파일로 설정하며 하나의 코드 저장소에는 여러 개의 워크플로우, 즉 여러 개의 YAML 파일을 생성합니다.
- on 속성을 통해 해당 워크플로우가 언제 실행되는지 정의합니다.
- (on: push: branches: master코드 저장소의 main 브랜치에 push 이벤트가 발생할 때마다 워크플로우를 실행하도록 설정)
- (on: schedule: cron: “0 0 * * *”: 매일 자정에 워크플로우 실행)
Jobs
- Github Actions에서 작업(Job)이란 독립된 가상 머신(machine) 또는 컨테이너(container)에서 돌아가는 하나의 처리 단위를 의미합니다.
- 하나의 워크플로우(Workflow)는 여러 개의 작업(Jobs)으로 구성되며 적어도 하나의 작업(Job)은 있어야 합니다.
runs-on
- 리눅스나 윈도우즈와 같은 실행 환경을 지정하는 옵션입니다.
Steps
- 정말 단순한 작업이 아닌 이상 하나의 작업(Job)은 여러 단계의 명령(Step)으로 모델링이 됩니다.
- 작업 단계는 단순한 커맨드(command)나 스크립트(script)가 될 수도 있고 액션(action)이 될 수도 있습니다.
Actions
- 복잡하거나 자주 반복되는 작업을 미리 정의해 놓은 Application입니다.
- 직접 Actions를 정의하여 사용할 수도 있으며, Github Marketplace에 이미 많은 Actions가 업로드되었습니다.
대표적인 공개 액션
- actions/checkout
Runner
- 트리거 된 workflow를 실행하는 서버
- 한 번에 하나의 Job을 수행할 수 있습니다.
- Runner 제공 OS: ubuntu, windows, MacOS
커맨드나 스크립트를 실행할 때 run 속성 사용하고, 액션을 사용할 때는 uses 속성을 사용합니다.
큰 틀에서 봤을 때, Workflow > Jobs > Steps 으로 구성함을 확인할 수 있습니다. 이제 위 개념들을 기반으로 스크립트를 작성해 보도록 하겠습니다.
deploy.yml
name: Deploy
// Github Actions 워크플로우의 이름 설정
on:
push:
branches:
- master
// 워크플로우가 실행되는 트리거 설정, 여기서는 마스터 브랜치에 푸쉬가 발생할 때 마다 워크플로우 실행
permissions:
contents: read
// 워크플로우가 저장소의 내용을 읽을 수 있는 권한을 가지도록 설정
jobs:
build:
// 워크플로우에서 실행할 작업 설정 (여기에서는 빌드 작업을 실행)
runs-on: ubuntu-latest
// 워크플로우가 실행될 가상 환경을 설정(여기서는 최신의 우분투 버전에서 실행)
steps:
// job의 단계를 설정, 각 단계는 순서대로 실행
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
package: 'jdk'
jdk-version: '17.0.9'
// Github Actions에서 제공하는 setup-java actions을 사용하여 JDK 17 설정
- name: checkout
uses: actions/checkout@master
// Github Actions에서 제공하는 checkout 액션을 사용하여 워크플로우가 실행되는 저장소의 코드를 체크아웃
- name: create env and secure file
run: |
touch .env
echo "${{ secrets.ENV_VARS }}" >> .env
cd src/main/resources
touch secure.properties
echo "${{ secrets.SECURE_VARS }}" >> secure.properties
// .env 파일, secure.properties 파일을 만들고, 이 파일들에 Github Secrets에서 제공하는 환경 변수를 추가합니다.
- name: Grant execute permission for gradlew
run: chmod +x gradlew
// Gradlew 파일에 실행 권한 부여
- name: Build with Gradle
run: ./gradlew clean build
// Gradle을 사용하여 프로젝트 build
- name: Image build and push
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker-compose -f docker-compose-prod.yml build
docker push a8118199/allercheck_app
// Docker 로그인, 이미지 빌드 및 푸쉬를 수행
- name: Up docker-compose
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }} # EC2 인스턴스 퍼블릭 DNS
username: ubuntu
key: ${{ secrets.SSH_PRIVATE_KEY }} # pem 키
passphrase: ${{ secrets.SSH_PASSPHRASE }}
# 도커 작업
script: |
sudo docker stop ubuntu_app_1
sudo docker rm ubuntu_app_1
sudo docker rmi seungbeom1234/allercheck_app
sudo docker pull seungbeom1234/allercheck_app
sudo docker-compose -f docker-compose-prod.yml up -d
// Github Actions에서 제공하는 ssh-action을 사용하여 EC2 인스턴스에 SSH 접속 후, Docker 컨테이너를 중지, 삭제, 이미지를 다시
받아오고, Docker-compose를 통해 프로젝트를 다시 시작
환경 변수 설정
- settings → Security → Secrets and variables
- DOCKER_PASSWORD : dockerhub password
- DOCKER_USERNAME : dockerhub username
- EC2_HOST = PUBLICS IP
- ENV_VARS = env 파일
- SECURE_VARS = security.properties 파일
- SSH_PRIVATE_KEY = ssh.
다음 스크립트를 .githubs/workflow 디렉토리 안에 넣어주시면 됩니다. 스크립트를 작성함으로써, 애플리케이션의 빌드, 테스트를 자동화할 수 있을뿐더러 지속적인 배포까지 가능하게 되었습니다.
이상으로 포스팅 마치겠습니다.
'DevOps' 카테고리의 다른 글
[Mysql] MYSQLWorkbench tool을 이용하여 DB ERD 추출 (0) | 2023.05.28 |
---|