[AWS/배포] Nginx + GitHub Actions로 Spring Boot & FastAPI CI/CD 자동 배포하기 (2) - deploy.yml 및 DockerFile 생성

2025. 8. 7. 01:00CS

 

 

 

 

 

저번 시간에 인스턴스를 생성하였으니,
이번 시간에는 본격적으로 GitHub Actions를 사용한 CI/CD 자동 배포 환경을 구축해보겠습니다.

저는 Docker를 사용하여 하나의 EC2 안에 SpringBoot, FastAPI, Nginx 컨테이너를 생성하였습니다.

1. REPO_BE : deploy.yml 및 dockerfile 생성
2. REPO_AI : deploy.yml 및 dockerfile 생성

 

GitHub Repostory 구조

아래 처럼 AI, BE 그리고 EC2 배포를 위한 레포지토리를 각각 구성하였습니다.
infra 레포지토리를 별도로 둔 이유는 AI와 BE 레포지토리에서는 빌드하여 도커이미지를 생성하는 것 까지 실행하고,
infra 레포지토리에서 EC2 배포를 통합하여 관리하기 위해서 입니다.


SpringBoot Repository

프로젝트이름/.github/workflows/deploy_be.yml

GithubActions를 설정하기 위해서는 해당 위치에 deploy.yml을 작성해주어야합니다.
secrets는 setting에 들어가서 Actions에 저장해줍니다.

  • develop 브랜치에 push가 발생하면
  • JDK 17 환경을 준비하고
  • application.yml을 secrets에서 받아 생성한 뒤
  • Gradle로 빌드하고
  • Docker 이미지로 만들고 Docker Hub에 푸시합니다.
name: Deploy REPO_BE

on:
  push:
    branches: [ develop ]

permissions:
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      # 1. 코드 체크아웃
      - name: Checkout
        uses: actions/checkout@v3

      # 2. JDK 17 설정
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: '17'

      # 3. application.yml 생성
      - name: Make application.yml
        run: |
          mkdir -p ./src/main/resources
          echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml
        shell: bash

      # 4. Gradle 빌드
      - name: Build with Gradle
        run: |
          chmod +x ./gradlew
          ./gradlew clean build -x test

      # 5. Docker 이미지 빌드 및 Docker Hub 푸시
      - name: Docker build & push
        run: |
          echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
          docker build -t ${{ secrets.DOCKER_REPO }}:latest .
          docker push ${{ secrets.DOCKER_REPO }}:latest
            sudo docker image prune -f

on:
  push:
    branches: [ develop ]
  • develop 브랜치에 push가 일어나면 이 워크플로우가 실행됩니다.
permissions:
  contents: read
  • 현재 워크플로우의 권한을 제한적으로 설정 (레포지토리 콘텐츠 읽기 권한만 허용)

jobs.deploy 섹션

jobs:
  deploy:
    runs-on: ubuntu-latest
  • 이 배포 작업은 GitHub에서 제공하는 Ubuntu 최신 버전의 가상 머신에서 실행됩니다.

1. 코드 체크아웃

- name: Checkout
  uses: actions/checkout@v3
  • 현재 레포지토리의 코드를 GitHub Actions runner에 가져옵니다.

2. JDK 17 설치

- name: Set up JDK 17
  uses: actions/setup-java@v3
  with:
    distribution: 'adopt'
    java-version: '17'
  • AdoptOpenJDK 17을 설치하여 Java 기반 프로젝트(Sprint Boot 등)를 빌드할 수 있도록 환경을 설정합니다.

3. application.yml 생성

- name: Make application.yml
  run: |
    mkdir -p ./src/main/resources
    echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml
  shell: bash
  • src/main/resources 경로에 application.yml 파일을 생성합니다.
  • 내용은 GitHub에 등록한 secret 변수 ${{ secrets.APPLICATION_YML }}에서 가져옵니다.
    • 즉, .yml 파일을 직접 커밋하지 않고 GitHub Actions 실행 시에만 생성하도록 설정 (보안상 안전)

4. Gradle 빌드

- name: Build with Gradle
  run: |
    chmod +x ./gradlew
    ./gradlew clean build -x test
  • ./gradlew에 실행 권한을 부여하고
  • Gradle 빌드 실행 (test는 제외)

5. Docker 이미지 빌드 및 푸시

- name: Docker build & push
  run: |
    echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
    docker build -t ${{ secrets.DOCKER_REPO }}:latest .
    docker push ${{ secrets.DOCKER_REPO }}:latest
    sudo docker image prune -f 
  • Docker Hub에 로그인
    • 로그인 정보는 GitHub Secrets에서 가져옴 (DOCKER_USERNAME, DOCKER_PASSWORD)
  • 현재 디렉토리(.) 기준으로 Dockerfile을 사용해 이미지를 빌드
    • 태그는 ${{ secrets.DOCKER_REPO }}:latest (예: hhongyeahh/evertale-be:latest)
  • 빌드한 이미지를 Docker Hub에 푸시
  • 사용하지 않는 로컬 Docker 이미지를 삭제 (docker image prune -f)

프로젝트 루트 위치에 DockerFile 작성

FROM openjdk:17-jdk-slim
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

 

develop 브랜치에 merge후 workflows가 정상적으로 작동할 경우 아래와 같은 화면 확인 가능


FastAPI Repository

FastAPI Repository에도 동일하게 deploy.yml과 dockerFile을 작성합니다.
구조는 SpringBoot와 거의 유사하며 프레임워크의 차이로 코드에도 차이점이 있습니다.

프로젝트이름/.github/workflows/deploy_be.yml

name: Deploy REPO_AI

on:
  push:
    branches: [ develop ]

permissions:
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      # 1. 코드 체크아웃
      - name: Checkout
        uses: actions/checkout@v3

      # 2 .env 파일 생성
      - name: Create .env file
        run: |
          echo "${{ secrets.FASTAPI_ENV }}" > .env
        shell: bash

      # 3. DockerHub 로그인 & 이미지 빌드/푸시
      - name: Docker build & push
        run: |
          echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
          docker build -t ${{ secrets.DOCKER_REPO }}:latest .
          docker push ${{ secrets.DOCKER_REPO }}:latest

 


프로젝트 루트 위치에 DockerFile 작성

# 1. Python 3.10 기반 슬림 이미지 사용
FROM python:3.10-slim

# 2. 작업 디렉토리 생성
WORKDIR /app

# 3. requirements.txt 먼저 복사하고 설치
COPY REPO_AI/requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# 4. 전체 코드 복사
COPY . .

# 5. 컨테이너가 열 포트 설정
EXPOSE 8000

# 6. FastAPI 실행 (앱 위치가 app/main.py)
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

 

develop 브랜치에 merge후 workflows가 정상적으로 작동할 경우 아래와 같은 화면 확인 가능

 

 

 

 

2025.08.07 - [CS] - [AWS 배포 가이드] Nginx + GitHub Actions로 Spring Boot & FastAPI CI/CD 자동 배포하기 (3) - Nginx reverse proxy / docker-compose.yml 생성

 

[AWS 배포 가이드] Nginx + GitHub Actions로 Spring Boot & FastAPI CI/CD 자동 배포하기 (3) - Nginx reverse proxy / doc

지난 시간에 BE와 AI 레포지토리의 GitHub Actions 설정을 모두 완료했습니다.이제는 인프라 설정을 관리하는 infra 레포지토리에서 다음 작업을 진행하겠습니다1. docker-compose.ymlSpring Boot, FastAPI, Nginx를

hhongyeahh.tistory.com