일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- springboot
- 2178
- 운영체제
- CPU스케줄링
- fatch
- DB replication
- 임베디드타입
- findById
- 프로젝트
- JPA
- Spring JPA
- 폰켓몬
- 산업은행청년인턴
- 코테
- 백준
- 트리맵
- 스케일아웃
- SpringBatch
- CS
- 그래프탐색
- 해시
- flyway
- 프로그래머스
- 구현
- 컴퓨터구조
- 파이널프로젝트
- 산업은행it
- 외래키제약조건위반
- BFS
- 트리셋
- Today
- Total
나 JAVA 봐라
Github Actions 로 배포 자동화하기 본문
Spring Boot 프로젝트를 EC2에 배포하고 보니, 아직 완성 안된 기능들을 추가해야할 때 jar 파일 빌드 → image로 생성하여 docker hub에 업로드 → EC2에서 프로젝트 이미지 pull → 컨테이너 생성 및 실행…
과 같이 하나하나 해줘야하는 것들이 많고 이 과정이 자동화가 된다면 서비스를 유지보수 하는 것에 있어 편리하겠다는 생각을 했다. 왜 사람들이 Github Action을 쓰는지 이해했다.
GitHub Actions 동작 순서
- Github Repository에 프로젝트의 추가사항이나 변경사항을 push 혹은 merge한다.
- 테스트 코드를 통과하면 push 혹은 merge가 된다.
- Github Actions에서 push 혹은 merge가 된 것을 확인한다.
- Project 빌드에 필요한 application.yml 파일 생성한다.
- Update된 Project를 빌드한다.
- 빌드한 결과로 Docker Image 생성한다.
- Docker Hub에 로그인한다.
- 생성한 Docker Image를 Docker Hub에 업로드한다.
- EC2 Instance에 SSH로 접속한다.
- Docker Hub에 업로드 된 이미지를 pull 받아 컨테이너 생성 및 실행
- 위의 과정을 수행하기 위해서는 Docker Hub 회원 가입, EC2 인스턴스 생성 및 Docker 설치가 진행되어야 한다.
빌드에 필요한 application.yml 생성
우리 프로젝트의 application.yml에는 DB에 연결하기 위한 URL, username, password 등의 민감한 정보가 포함되어 있어 gitignore에 추가되어 있다. 그렇기 때문에 로컬 개발 환경에서는 사용 가능하지만, Github Actions을 통해 빌드하면 프로젝트에 꼭 필요한 정보들이 포함되지 않은 채로 빌드 된다.
그렇다고 application.yml에 있는 파일을 같이 push 할 수없으니 github action에서 어떻게 추가해야할까?
Github Actions에는 secret 값을 설정할 수 있는 기능이 있다. 해당 기능 통해 secret 값을 설정하면 민감한 정보를 secret을 통해 가져올 수 있다. 나는 APPLICATION 이름을 가진 secret을 생성했다. 값으로는 application.yml 파일을 복붙했다.
## application.yml
spring:
datasource:
url: 링크 ~~
driver-class-name: com.mysql.cj.jdbc.Driver
username: 아이디 ~
password: 비번 ~
secret 값을 생성했다면 GitHub Actions에서 프로젝트가 빌드되기 전에 해당 값을 가져와야 한다.
## .github/workflows/github-action.yml
## application.yml 생성 후 secret 값 복붙
- uses: actions/checkout@v3
- run: touch ./src/main/resources/application.yml
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
- run: cat ./src/main/resources/application.yml
로컬 환경과 똑같은 경로에 application.yml을 생성한 후, APPLICATION 이라는 이름을 가진 secret의 값을 넣어준다. 이 후 Build를 진행한다.
전체 코드는 아래와 같다. 코드의 순서는 제일 위에 작성된 Github Actions 동작순서를 참고하면 된다 !
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CD with Gradle
on:
push:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
## jdk setting
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
## application.yml 생성 후 secret 값 복붙
- uses: actions/checkout@v3
- run: touch ./src/main/resources/application.yml
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
- run: cat ./src/main/resources/application.yml
# Gradle Build를 위한 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# Gradle Build (test 제외)
- name: Build with Gradle
run: ./gradlew clean build -x test
# DockerHub 로그인
- name: DockerHub Login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# Docker 이미지 빌드
- name: Docker Image Build
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }} . --platform=linux/amd64
# DockerHub Push
- name: DockerHub Push
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
# EC2 인스턴스 접속 및 애플리케이션 실행
- name: Application Run
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_KEY }}
script: |
sudo docker kill ${{ secrets.PROJECT_NAME }}
sudo docker rm -f ${{ secrets.PROJECT_NAME }}
sudo docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
sudo docker run -p ${{ secrets.PORT }}:${{ secrets.PORT }} -v mysql-volume:/var/lib/mysql --name ${{ secrets.PROJECT_NAME }} -d ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
또 다른 방법들
해당 배포 방법에 대해 다른 사람들의 피드백을 받았다.
- jasypt를 사용하여 .yml 을 암호화하기
- 서브 모듈 생성하기
- 키 값을 들고있는 private repository 생성
참고)
GitHub-Actions로 CI/CD 구축하기(AWS, Docker, SpringBoot)
'DevOps, MLOps' 카테고리의 다른 글
AWS Lambda에서 CloudWatch Logs 접근하기 (0) | 2024.06.05 |
---|---|
AWS 서비스로 모니터링 환경 구축하기 (1) | 2024.06.05 |
DockerHub를 통해 EC2에 Spring boot, mysql 올리기 (3) | 2024.06.05 |
MLOps 개념 정리 (0) | 2024.06.03 |
[머신러닝 시스템 설계] 1장 머신러닝 시스템 개요 (0) | 2024.05.31 |