반응형
    
    
    
  GitHub Actions를 사용해 Spring Boot 애플리케이션을 빌드하고 Docker 이미지를 생성하여 Docker Hub에 업로드하는 방법
GitHub Actions 워크플로우
전체 워크플로우
더보기
---
name: Deploy Spring Boot Application
on:
  push:
    branches:
      - main
env:
  AWS_REGION: us-east-1
  SECURITY_GROUP_ID: sg-07f3
  CONTAINER_BASE_DIR: "/app/docker-container"
  CONTAINER_LOG_DIR: "$CONTAINER_BASE_DIR/logs"
  APPLICATION_PORT: 8080
  DOCKER_REPO: ${{ vars.DOCKER_REPO }}
  DOCKER_NAMESPACE: playground
  DOCKER_IMAGE_NAME: springboot-app
jobs:
  build:
    name: Build and Push Docker Image
    runs-on: ubuntu-latest
    steps:
      # 코드 체크아웃
      - name: Checkout code
        uses: actions/checkout@v4
      # Java 21 설정
      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
      # Gradle 빌드
      - name: Build with Gradle
        run: |
          chmod +x gradlew
          ./gradlew clean build
      # Docker 이미지 태그 생성
      - name: Set Docker Tag
        id: set_docker_tag
        run: echo "DOCKER_TAG=$(echo $GITHUB_SHA | cut -c 1-7)" >> $GITHUB_ENV
      # Docker 이미지 빌드
      - name: Build Docker Image
        run: |
          docker build -t ${{ vars.DOCKER_REPO }}/${{ env.DOCKER_IMAGE_NAME }}:latest .
      # Docker Hub에 이미지 푸시
      - name: Push Docker Image to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ vars.DOCKER_REPO }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - run: |
          docker tag ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE_NAME }}:latest \
            ${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-$DOCKER_TAG
          docker push ${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-$DOCKER_TAG
          echo "Docker Image: ${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-$DOCKER_TAG"
      # 빌드 아티팩트 업로드
      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-artifacts
          path: build/libs/*-SNAPSHOT.jar
          overwrite: true
  deploy:
    name: Deploy Application
    runs-on: ubuntu-latest
    needs: build
    steps:
      # 애플리케이션 배포
      - name: Deploy Docker Image
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ vars.AWS_EC2_HOST }}
          username: ${{ vars.AWS_EC2_USER }}
          key: ${{ secrets.AWS_EC2_SSH_KEY }}
          script: |
            FQ_IMAGE=${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-${{ env.DOCKER_TAG }}
            mkdir -p ${{ env.CONTAINER_BASE_DIR }}
            cd ${{ env.CONTAINER_BASE_DIR }}
            docker compose down -v || true
            docker rmi -f $(docker images | grep ${{ env.DOCKER_IMAGE_NAME }}  | awk '{print $3}' | uniq) || true
            docker pull $FQ_IMAGE
            cat <<EOF > ${{ env.CONTAINER_BASE_DIR }}/docker-compose.yml
            services:
              ${{ env.DOCKER_IMAGE_NAME }}:
                image: $FQ_IMAGE
                container_name: ${{ env.DOCKER_IMAGE_NAME }}
                restart: unless-stopped
                ports:
                  - "${{ env.APPLICATION_PORT }}:${{ env.APPLICATION_PORT }}"
            EOF
            docker compose up -d || echo "Failed to start the container"
  status:
    name: Health Check
    runs-on: ubuntu-latest
    needs: deploy
    steps:
      # 애플리케이션 헬스 체크
      - name: Check Application Health
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ vars.AWS_EC2_HOST }}
          username: ${{ vars.AWS_EC2_USER }}
          key: ${{ secrets.AWS_EC2_SSH_KEY }}
          script: |
            curl -fsSL http://localhost:${{ env.APPLICATION_PORT }} || echo "Health check failed"---
1. 트리거
name: Deploy Spring Boot Application
on:
  push:
    branches:
      - main2. 환경 변수
env:
  AWS_REGION: us-east-1
  SECURITY_GROUP_ID: sg-07f3
  CONTAINER_BASE_DIR: "/app/docker-container"
  CONTAINER_LOG_DIR: "$CONTAINER_BASE_DIR/logs"
  APPLICATION_PORT: 8080
  DOCKER_REPO: ${{ vars.DOCKER_REPO }}
  DOCKER_NAMESPACE: playground
  DOCKER_IMAGE_NAME: springboot-app3. Build Job
코드 체크아웃
- GitHub 저장소에서 코드를 가져옵니다.
# 코드 체크아웃
- name: Checkout code
  uses: actions/checkout@v4Java 21 설치
- JDK(Java)를 설치합니다
# Java 21 설정
- name: Set up JDK 21
  uses: actions/setup-java@v4
  with:
    java-version: '21'
    distribution: 'temurin'Gradle 빌드
- 애플리케이션을 빌드합니다.
# Gradle 빌드
- name: Build with Gradle
  run: |
    chmod +x gradlew
    ./gradlew clean buildDocker 태그 생성
- 현재 Git 커밋 SHA의 처음 7자로 DOCKER_TAG 환경 변수를 생성합니다.
# Docker 이미지 태그 생성
- name: Set Docker Tag
  id: set_docker_tag
  run: echo "DOCKER_TAG=$(echo $GITHUB_SHA | cut -c 1-7)" >> $GITHUB_ENV- Dockerfile 코드
FROM openjdk:21-jdk-slim
ARG JAR_FILE=build/libs/*-SNAPSHOT.jar
WORKDIR /app
COPY ${JAR_FILE} /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]Docker 이미지 빌드 및 푸시
- Docker 이미지를 빌드하고 Docker Hub에 이미지를 푸시합니다.
# Docker 이미지 빌드
- name: Build Docker Image
  run: |
    docker build -t ${{ vars.DOCKER_REPO }}/${{ env.DOCKER_IMAGE_NAME }}:latest .
# Docker Hub에 이미지 푸시
- name: Push Docker Image to Docker Hub
  uses: docker/login-action@v3
  with:
    username: ${{ vars.DOCKER_REPO }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}
- run: |
    docker tag ${{ env.DOCKER_REPO }}/${{ env.DOCKER_IMAGE_NAME }}:latest \
      ${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-$DOCKER_TAG
    docker push ${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-$DOCKER_TAG
    echo "Docker Image: ${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-$DOCKER_TAG"빌드 아티팩트 업로드(선택 사항)
- 빌드된 JAR 파일을 결과물로 업로드합니다.
# 빌드 아티팩트 업로드
- name: Upload build artifacts
  uses: actions/upload-artifact@v4
  with:
    name: build-artifacts
    path: build/libs/*-SNAPSHOT.jar
    overwrite: true4. Deploy Job
Docker 이미지 배포 및 도커 컴포즈 실행
- 기존 컨테이너를 중지 및 제거하고 새로운 이미지를 가져와 도커 컴포즈를 이용하여 애플리케이션을 실행합니다.
# 애플리케이션 배포
- name: Deploy Docker Image
  uses: appleboy/ssh-action@v1.2.0
  with:
    host: ${{ vars.AWS_EC2_HOST }}
    username: ${{ vars.AWS_EC2_USER }}
    key: ${{ secrets.AWS_EC2_SSH_KEY }}
    script: |
      FQ_IMAGE=${{ env.DOCKER_REPO }}/${{ env.DOCKER_NAMESPACE }}:${{ env.DOCKER_IMAGE_NAME }}-${{ env.DOCKER_TAG }}
      mkdir -p ${{ env.CONTAINER_BASE_DIR }}
      cd ${{ env.CONTAINER_BASE_DIR }}
      docker compose down -v || true
      docker rmi -f $(docker images | grep ${{ env.DOCKER_IMAGE_NAME }}  | awk '{print $3}' | uniq) || true
      docker pull $FQ_IMAGE
      cat <<EOF > ${{ env.CONTAINER_BASE_DIR }}/docker-compose.yml
      services:
        ${{ env.DOCKER_IMAGE_NAME }}:
          image: $FQ_IMAGE
          container_name: ${{ env.DOCKER_IMAGE_NAME }}
          restart: unless-stopped
          ports:
            - "${{ env.APPLICATION_PORT }}:${{ env.APPLICATION_PORT }}"
      EOF
      docker compose up -d || echo "Failed to start the container"5. Status Job
애플리케이션 헬스 체크
- cURL 명령어로 애플리케이션이 올바르게 실행 중인지 확인합니다.
# 애플리케이션 헬스 체크
- name: Check Application Health
  uses: appleboy/ssh-action@v1.2.0
  with:
    host: ${{ vars.AWS_EC2_HOST }}
    username: ${{ vars.AWS_EC2_USER }}
    key: ${{ secrets.AWS_EC2_SSH_KEY }}
    script: |
      curl -fsSL http://localhost:${{ env.APPLICATION_PORT }} || echo "Health check failed"
728x90
    
    
  반응형
    
    
    
  '리눅스' 카테고리의 다른 글
| SSL 인증서 확인 (0) | 2025.01.16 | 
|---|---|
| ps kill 명령어 (0) | 2025.01.16 | 
| 우분투 24.04에서 최신 버전의 Docker를 설치하는 방법 (0) | 2025.01.14 | 
| PHP-FPM Pool을 구성하는 방법 (1) | 2025.01.14 | 
| NGINX에서 가상 호스트에 HTTP2를 설정하는 방법 (0) | 2025.01.08 | 
 
                  
                 
                  
                 
                  
                