728x90
YAPP20기를 진행하면서 GitHub Actions + Docker를 이용하여 CI/CD를 구축하게 됐다
CI/CD를 해보고 싶었는데 마침 같이 BE를 맡으신 분은 이미 CI/CD를 경험해보셔서 나에게 맡겨주셨다
어떻게 진행했는지 기록하기 위해서 이 글을 써보려고 한다,,
EC2, RDS 생성
- 이동욱 님의 “스프링 부트와 AWS로 혼자 구현하는 웹 서비스"라는 책을 보면서 했다
암호화
- 실제 배포하기 위해서는 property 파일에 RDS, Docker, IP의 ID, PW를 입력해야한다
- 이는 노출되면 안되기 때문에 “jasypt”라는 것을 이용하여 암호화를 해준다
- 이때 암호화 key는 우리가 나중에 Docker를 실행할 때 환경변수로 지정해주면 된다
- 참고 : jasypt 사용
spring:
datasource:
url: ENC(LbJ/mHuNdf8ev0K55UK22Fu1IG78TZT6PPMNQTp3Qr8f6F6imvQ0WYkZNx2kkq3RWxkdviucv4dTVqRZ7zKFhAluy1tk4kO1xQvPk5L2/MvHXjR9MQykrbZkROeUz7Ue)
username: ENC(OTUfXu9X9QBk4lG0mm19+A==)
password: ENC(8d+CPaIyBQOntW/l/k6WlE9NqDqx5eoR)
driver-class-name: com.mysql.cj.jdbc.Driver
- ENC를 감싸서 암호를 작성하면 된다
- 키 값은 나중에 Docker를 실행할 때 환경변수로 지정
오류
- jasypt를 사용하면서 생겼던 오류는 아니지만 해당 부분에서 오류가 생겨 적어본다
- url을 처음 적었을 때는 RDS의 엔드포인트만 적었다,,
- “Driver com.mysql.cj.jdbc.Driver claims to not accept jdbcUrl” 발생
해결
- url을 jdbc:mysql://[RDS 엔드포인트]:[포트번호]/[스키마 이름]으로 작성했다
Dockerfile 생성
- 애플리케이션을 Docker를 이용하여 배포를 하기 때문에 Dockerfile을 생성해야한다
Dockerfile
FROM openjdk:11 as build
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-jar","/app.jar"]
- Docker 공식문서를 통해서 해당 명령어들의 설명을 볼 수 있다
- 제일 중요한 부분은 “-Dspring.profiles.actvie=dev”이다
- 이번에 property 파일을 local과 dev(배포용)을 사용하기 때문에 Docker가 어느 파일을 선택할 지 결정해주는 명령어다
오류
- 초기에는 “application-dev”, “application-local”, “application” 프로퍼티 파일들이 존재했다
- 하지만 실제로 Docker를 실행했더니 위와 같이 Dockerfile을 설정해도 application 파일을 읽었다
해결
- application 파일을 삭제하니 application dev로 잘 실행이 됐다
GitHub Actions을 이용한 CI 구축
name: Togather
env:
TOGATHER_JASYPT_PASSWORD: ${{ secrets.TOGATHER_JASYPT_PASSWORD }}
# main branch에 push를 날릴 경우 GitHub Action을 실행
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
# github repository에 접근하기 위해 check-out 하는 GitHub Action 공식 작업
# link : <https://github.com/actions/checkout>
steps:
- name: Checkout
uses: actions/checkout@v3
# java version을 다운받고 setting 및 다른 부가 기능을 한다
# link : <https://github.com/actions/setup-java>
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'adopt' #OpenJDK HotSpot을 사용한다
java-version: '11'
# gradlew를 실행시키기 위해 권한 설정
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# 요건 github action이 제공하는 스크립트 가져왔다
# 기존 build한 파일이 존재한다면 캐싱하여 build 속도를 높일 수 있다~
- name: cache
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew build
# docker container builder driver를 사용하여 builder를 만들고 부팅
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# docker hub 대한 로그인 처리
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# docker image생성하고 DockerHub에 push 한다
- name: Build and push to DockerHub
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ secrets.DOCKER_TAG }}
${{ }}
- 암호화한 정보들을 의미한다
- github의 repository setting에서 생성할 수 있다
GitHub Actions을 이용한 CD 구축
deploy:
needs: build
name: Deploy
runs-on: [ self-hosted, label-development ]
steps:
- name: Docker run
run: |
sudo docker stop yapp && docker rm yapp && docker rmi ${{ secrets.DOCKER_TAG }}
sudo docker run -d -p 8080:8080 -e TOGATHER_JASYPT_PASSWORD=${{ secrets.TOGATHER_JASYPT_PASSWORD }} --name yapp ${{ secrets.DOCKER_TAG }}
GitHub Actions이 제공하는 Runner 사용
- repository setting에서 좌측 Actions → Runners → New self-hosted runner를 생성
- 생성 버튼을 누르면 위와 같은 script의 문장을 하나하나 EC2에 복붙한다
- echo ~ 부분은 제대로 작동되지 않는데 아마 큰 문제가 없는 듯하다(이거 안됐는데 CI/CD 성공함)
- 이때 download가 완료한 시점에 뭘 많이(2~3개?) 물어본다(이 때는 성공하려고 캡처 못함,,)
- 다른 건 enter를 쳐서 넘어갔는데 label~~ 뭐시기 얘기한 게 나온다
- 이 부분에서 우리가 script를 작성했을 때 사용했던 label을 입력해줘야한다
- runs on : “label-development”
- ./run.sh를 입력할 때 백그라운드에서 실행하기 위해 “nohub ./run.sh &”를 사용하자~
결과
- 위와 같은 사진처럼 Idle가 되면 잘 실행됨을 의미한다
오류
- GitHub Actions을 실행할 때 build는 제대로 작동됐는데 계속해서 deploy에서 잘못됐다
- 나는 label도 잘 입력하고, docker run 명령어도 잘 입력했는데 도대체 뭐가 문제일까라는 생각을 했다
해결
- 당연히 문제는 나에게 있었다 docker run 명령어가 제대로 작동하지 않았다
- 이 글을 보신 분들은 꼭 Action 실행시키기 전에 EC2에서 직접 docker 명령어가 실행되는지 확인하시길 바랍니다,,
- 과정을 설명하면 container 중지 → container 삭제 → image 삭제 → docker run
- 여기서 image를 삭제했는데 docker run이 당연히 작동하지 않나요!!? 라는 생각을 할 수 있다
- 하지만 DockerHub에 저장된 image를 실행시키는데 만약 image가 없다면 Docker가 DockerHub에 있는 image를 pull해준다(이 부분은 로그 보면서 알 수 있었음)
REFERENCES
728x90
'Infra' 카테고리의 다른 글
[prolog] prolog 에 로그 모니터링 시스템 구축기(2) (2) | 2023.08.02 |
---|---|
[prolog] prolog 에 로그 모니터링 시스템 구축기(1) (0) | 2023.08.02 |
[monitoring] local에서 filebeat + elasticsearch + grafana를 통해 모니터링 시스템 구축해보기 (2) | 2023.07.06 |
[Flyway] Flyway 사용해보기 (0) | 2023.06.07 |