반응형
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:
- main
2. 환경 변수
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
3. Build Job
코드 체크아웃
- GitHub 저장소에서 코드를 가져옵니다.
# 코드 체크아웃
- name: Checkout code
uses: actions/checkout@v4
Java 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 build
Docker 태그 생성
- 현재 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"
728x90
빌드 아티팩트 업로드(선택 사항)
- 빌드된 JAR 파일을 결과물로 업로드합니다.
# 빌드 아티팩트 업로드
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: build/libs/*-SNAPSHOT.jar
overwrite: true
4. 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 |
우분투에서 최신 버전의 Docker를 설치하는 방법 (0) | 2025.01.14 |
PHP-FPM Pool을 구성하는 방법 (0) | 2025.01.14 |
NGINX에서 가상 호스트에 HTTP2를 설정하는 방법 (0) | 2025.01.08 |