반응형
목적
Github는 Github Action이라는 레포지토리를 연동한 CI/CD를 제공합니다.
Github에서 제공하는 Runner를 이용하여 코드 배포시 도커 이미지를 만들어 서버에 배포하는작업을 자동화 하고자 합니다.
방법
Github Action으로 CI/CD를 하기 위해서는 .github/workflows 내에 yml 파일을 만들어야 합니다.
1. 조건 설정
우선 적당한 이름으로 yml 파일을 만들어 준뒤 이름과 조건을 설정합니다.
이번 예제에서는 workflow.yml로 하였습니다.
name: Docker Build and Deploy
on:
# Workflow Manual
workflow_dispatch:
inputs:
isRequiredRemoteDeploy:
type: boolean
description: 원격 서버 배포
# Workflow Event
#push:
# branches: [ master ]
#pull_request:
# branches: [ master ]
push 및 pull_request 필드 밑에 브랜치를 설정하여 브랜치를 한정할 수 있으며, 액션 수행 브랜치를 특정할 수 있습니다.
또한 input을 이용해 여러 입력을 제어할 수 있습니다.
(이번 예제에서는 원격 서버에 배포를 할지 여부를 선택할 수 있도록 하였습니다.)
2. 환경 변수 설정
yml 파일 내에서 사용할 환경 변수들을 지정합니다.
별도로 지정하지 않고 직접 쓸 수도 있지만 반복 사용되거나 한곳에서 관리하기 편하게 하기 위해서 지정해주는 것이 좋습니다.
env:
CACHED_BUILD_PATHS: ${{ github.workspace }}/build
BUILD_CACHE_KEY: ${{ github.sha }}
REGISTRY_URL: registry.gitlab.com/codingflowerdog/dev
REGISTRY_NAME: spring-boot-example
3. 잡 설정
job은 Github Action의 수행 액션을 지정하는 필드입니다.
아래 예제에서는 다음과 같이 3단계로 나누어 설정했습니다.
- gradle-build : JAVA 빌드
- docker-build : 도커 이미지 빌드
- deploy : 이미지 배포
또한 각 단계에서 슬랙으로 결과를 전송하도록 하였으며 사용한 패키지는 8398a7/action-slack@v3 입니다.
jobs:
# Gradle Build
gradle-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# JAVA 설정
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
# Gradle build
- name: Build with Gradle
id: gradle-build
run: |
chmod +x gradlew
./gradlew build
# 빌드 결과 업로드
- name: Upload Build File
uses: actions/upload-artifact@v2
with:
name: build
path: build/libs/app.jar
# 빌드 결과 알림
- name: Notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: Github Action Notification
fields: repo, message, commit, workflow, job, took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# Docker Build
docker-build:
runs-on: ubuntu-latest
needs: gradle-build
steps:
- uses: actions/checkout@v2
# 빌드 결과 다운로드
- name: Download Build File
uses: actions/download-artifact@v2
with:
name: build
# 빌드 파일 경로 설정
- name: Create Build Directory
run: |
mkdir -p build/libs
mv app.jar build/libs/app.jar
# Docker 빌드
- name: Docker Build
run: |
docker build -t spring-boot-example .
docker tag spring-boot-example:latest ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
# Upload Docker Image Artifact
- name: Upload Docker Image Artifact
uses: ishworkh/docker-image-artifact-upload@v1
with:
image: ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
# 빌드 결과 알림
- name: Notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: Github Action Notification
fields: repo, message, commit, workflow, job, took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# Deploy
deploy:
runs-on: ubuntu-latest
needs: docker-build
steps:
# Download Docker Image Artifact
- name: Download Docker Image Artifact
uses: ishworkh/docker-image-artifact-download@v1
with:
image: ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
# Gitlab 로그인
- name: Gitlab Login
run: docker login https://registry.gitlab.com/my_registry -u ${{ secrets.GITLAB_USER_NAME }} -p ${{ secrets.GITLAB_CONTAINER_ACCESS_TOKEN }}
# Docker Push
- name: Gitlab Push
run: docker push ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
# 배포 결과 알림
- name: Notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: Github Action Notification
fields: repo, message, commit, workflow, job, took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# Remote Deploy
- name: Remote Deploy
if: ${{ github.event.inputs.isRequiredRemoteDeploy }} == 'true'
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_SSH_ID }}
key: ${{ secrets.REMOTE_SSH_KEY }}
port: ${{ secrets.REMOTE_SSH_PORT }}
script: |
bash --login <<EOF
docker pull ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
docker run -it -d -p ${{ secrets.DOCKER_PORT }}:${{ secrets.APPLICATION_PORT }} --name ${{ env.REGISTRY_NAME }} ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
EOF
# 원격 서보 배포 결과 알림
- name: Notification
if: ${{ github.event.inputs.isRequiredRemoteDeploy }} == 'true'
uses: 8398a7/action-slack@v3
with:
status: custom
author_name: Github Action Notification
custom_payload: |
{
"attachments": [{
color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Remote Deploy :computer:",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Host*\n${{ secrets.REMOTE_HOST }}"
},
{
"type": "mrkdwn",
"text": "*Registry*\n${{ env.REGISTRY_URL }}"
},
{
"type": "mrkdwn",
"text": "*Docker Image*\n${{ env.REGISTRY_NAME }}"
},
{
"type": "mrkdwn",
"text": "*Tag*\n${{ github.run_number }}"
}
]
}
]
}]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
한 가지 주의할 점은 위 코드처럼 Job을 분리하면 각 Job들의 수행 결과가 공유되지 않는다는 것입니다.
예제에서는 도커 이미지 빌드 결과를 전달하기 위해 artifact에 업로드 후 다음 job에서 다운로드 하여 사용하고 있습니다.
업로드
# Upload Docker Image Artifact
- name: Upload Docker Image Artifact
uses: ishworkh/docker-image-artifact-upload@v1
with:
image: ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
다운로드
# Download Docker Image Artifact
- name: Download Docker Image Artifact
uses: ishworkh/docker-image-artifact-download@v1
with:
image: ${{ env.REGISTRY_URL }}/${{ env.REGISTRY_NAME }}:${{ github.run_number }}
결과
워크플로우 실행 화면
워크플로우 실행 결과
artifact 업로드 결과
반응형
'개발 > java' 카테고리의 다른 글
QueryDsl SpringBoot JPA 레포지토리 만들기 (0) | 2023.05.19 |
---|---|
JPA 데이터 소스 여러개 적용하기 (0) | 2023.05.18 |
actuator사용시 Swagger 3.0과 충돌하는 현상 해결법 (0) | 2023.05.03 |
gradle 빌드시 plain .jar파일 제외하기 (0) | 2023.05.03 |
스프링부트 CORS 클래스 설정 방법 (0) | 2023.05.03 |