본문 바로가기

개발

[Github Action] CI/CD 구현

" GitHub Actions를 사용하여 CI/CD 파이프라인을 구성하고

Docker 이미지를 빌드한 뒤

Oracle Cloud 서버에 전송하여 자동 배포하자"


이 글의 예제 프로젝트의 스펙

  • 백엔드 프레임워크: Python 3.x / FastAPI
  • 서버 : Oracle Cloud 무료 VM 인스턴스 (Always Free Tier)
  • 배포 방식 : Docker 컨테이너 기반 이미지 생성 및 실행, GitHub Actions를 활용한 CI/CD 자동화 파이프라인 구축
  • Git 저장소 : Github에 올라가 있는 프로젝트여야 함

1. deploy-version.json

프로젝트 루트에 deploy-version.json 파일을 생성하고 아래처럼 작성 한다

이제 이 파일의 version값이 변경되면 Github Actions가 이것을 감지하고 자동으로 배포하게 할 것이다.

{
  "name": "프로젝트 이름",
  "version": "1.0.0",
  "description": "원한다면 설명 넣기"
}

 

+) frontend, backend가 같은 프로젝트에 함께 있다면
각각 deploy-version.json과 .github/workflows/deploy.yml을 분리해서 관리하는 것이 좋다고 한다.


2. yml 파일 작성

프로젝트 루트에 .github/workflows/deploy.yml 파일을 생성한다.

 

아래는 예시 deploy.yml 파일이다.

필요한 변수 등을 수정하여 사용할 수 있다.

주의 !!!!
HOST_PORT는 Oracle Cloud VM의 방화벽에서 허용된 포트여야 한다!! (oracle cloud vm instance를 사용할 경우)
해당 과정은 아래 링크의 글 중간의 5. Oracle Cloud에서 방화벽 열기 에서 확인할 수 있다.
https://yun000.tistory.com/329

 

deploy.yml 예시 탬플릿

name: Deploy Dockerized FastAPI to Oracle Cloud

on:
  push:
    branches:
      - main
    paths:
      - deploy-version.json
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

env:
  IMAGE_NAME: my-app               # 원하는 도커 이미지 이름
  CONTAINER_NAME: my-app           # 실행될 컨테이너 이름
  ARTIFACT_NAME: my-app.tar.gz     # 전송할 tar 파일 이름
  TARGET_DIR: /home/ubuntu/my-app  # 서버에서 사용할 디렉토리
  HOST_PORT: 8080                  # 외부에서 접근할 포트
  CONTAINER_PORT: 8000             # 앱이 내부에서 열 포트

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: 🍏 Checkout Repository
        uses: actions/checkout@v4

      - name: 🍏 Extract version from deploy-version.json
        run: |
          VERSION=$(jq -r .version < deploy-version.json)
          echo "VERSION=$VERSION" >> $GITHUB_ENV

      - name: 🍏 Create .env file from Secrets
        run: |
          echo "API_KEY=${{ secrets.API_KEY }}" > .env
          echo "NOT_SECRET_KEY=${{ vars.NOT_SECRET_KEY }}" >> .env
          echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env

      - name: 🍏 Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: 🍏 Build Docker Image
        run: docker build -t $IMAGE_NAME:${{ env.VERSION }} .

      - name: 🍏 Save Docker Image as Tarball
        run: docker save $IMAGE_NAME:${{ env.VERSION }} | gzip > $ARTIFACT_NAME

      - name: 🍏 Prepare upload directory
        run: |
          mkdir upload
          cp $ARTIFACT_NAME upload/
          cp .env upload/

      - name: 🍏 Copy to Oracle Cloud
        uses: appleboy/scp-action@v0.1.4
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER }}
          key: ${{ secrets.KEY }}
          source: upload/
          target: ${{ env.TARGET_DIR }}
          strip_components: 1

      - name: 🐳 Deploy on Oracle Cloud VM via SSH
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER }}
          key: ${{ secrets.KEY }}
          script: |
            cd ${{ env.TARGET_DIR }}
            docker load < ${{ env.ARTIFACT_NAME }}
            docker stop ${{ env.CONTAINER_NAME }} || true
            docker rm ${{ env.CONTAINER_NAME }} || true
            docker run -d --name ${{ env.CONTAINER_NAME }} \
              --env-file .env \
              -p ${{ env.HOST_PORT }}:${{ env.CONTAINER_PORT }} \
              ${{ env.IMAGE_NAME }}:${{ env.VERSION }}

      - name: 🍏 Clean up local temp files
        run: rm -rf upload .env $ARTIFACT_NAME

 


3. Github main 에 push

push branchesmain으로 해 놓았기 때문에 main 에 커밋.

커밋할 때는 deploy-version.json의 "version"을 꼭 바꿔주자. 그래야지 자동 배포된다.


4. github action 확인하기

github > 프로젝트를 선택 > Actions탭 

배포 되는 과정, 로그들을 확인할 수 있다.


4. 결과 확인

브라우저에서 확인하자

(ex: http://123.123.12.123:8080)