-
Github Actions를 이용한 CI / CD 구현하기GIT 2022. 11. 27. 15:01
이전에 Jenkins를 이용하여 CI / CD를 구현한 적이 있는데,
이 부분을 Github Action을 이용하면 매우 간단하게 진행된다고 하여 aws ec2환경에서 구현해보았다.
Github Action 테스트
먼저 테스트용 Github Action 파일을 작성하여 실행이 되는지 확인하였다. 확인 과정에서는 Ktlint를 이용하여 문법을 체크하도록 설정한다. 프로젝트에 ktlint plugin을 추가해준다.
↓
https://seosh817.tistory.com/154
[Kotlin/TDD] ktlint를 이용하여 코딩 컨벤션 맞추기
NextStep 이펙티브 코틀린 with TDD, Refactoring, Clean Code에서 배운 ktlint 설정 법을 정리해보고자 합니다. 린트 검사로 코드 개선 테스트를 빌드하여 앱이 기능적 요구사항을 충족하는지 확인하는 것 외
seosh817.tistory.com
plugins { id("org.jlleitschuh.gradle.ktlint") version "11.0.0" }
github action파일을 만들어준다.
# This is a basic workflow to help you get started with Actions name: Workflow # Controls when the workflow will run on: # Triggers the workflow on push or pull request events but only for the "main" branch push: branches: [ "main" ] pull_request: branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: testing: name: Lint Check and Testing runs-on: ubuntu-latest steps: - name: Clone Repo uses: actions/checkout@v1 - name: Set up JDK 11 uses: actions/setup-java@v1 with: java-version: '11' - name: Run Kotlin Linter run: ./gradlew ktlintCheck
수정한 코드를 main 브랜치에 push하면 action이 실행된다.
만약 여기서 build.gradle.kts에서 tab 오류가 발생한다면 tab -> 스페이스 4번으로 교체해준다.
↓
[Lint] ktlint 를 사용한 Coding Convention 맞추기
Coding Convention 을 쉽게 맞출 수 있는 Lint 에 대하여 공부를 진행하다가, ktLint 라는 것이 있어서 확인해 보았는데, 적용 및 사용 방법이 간단하여 한번 사용해 보았다. ktLint 란 무엇인가 ? kotlin 환경
heegs.tistory.com
CI
이제 프로젝트를 CI 를 구현해보자. CI에서는 프로젝트 commit -> Github Action에서 빌드 -> 빌드된 jar 파일을 docker hub에 이미지 올리기 의 과정을 수행한다.
먼저도커 hub에 가입한다.
Docker Hub Container Image Library | App Containerization
Deliver your business through Docker Hub Package and publish apps and plugins as containers in Docker Hub for easy download and deployment by millions of Docker users worldwide.
hub.docker.com
여기서 이미지 빌드를 위해서 가입할 때 사용되었던 Docker username(닉네임이나 이메일)과 비밀번호를 github action에 등록해준다.github action은 여기에 저장된 secret값을 이용해서 action을 실행한다.
그다음 build.gradle.kts에 다음과 같이 설정해주는데, 이 부분은 기본적으로 Jar 파일이 실행 가능한 Jar, 비어있는 Jar 2개가 생성되는 것을 방지하고 실행 가능한 Jar만을 생성하도록 설정한다.
↓
https://blog.leocat.kr/notes/2020/01/23/gradle-create-executable-jar-with-spring-boot
[Gradle] Spring Boot 플러그인으로 실행가능한 executable jar 만들기 (feat. 그런데 실행이 안 돼요)
Spring Boot Gradle Plugin을 사용하면 손쉽게 실행가능한 jar(executable jar)를 만들 수 있다. jar 뿐만 아니라 war 등도 만들 수 있다. 설정도 아주 쉽다.
blog.leocat.kr
tasks.jar { enabled = false } tasks.bootJar { enabled = true }
Docker 이미지 생성 설정을 위해 프로젝트에 다음과 같이 Dockerfile을 만들어준다. 이 Dockerfile의 설정은 생성된 jar 파일을 app.jar로 복사한다.
FROM openjdk:11.0.10-jre-slim-buster ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]
이제 action을 이용해서 이미지를 빌드해보자.
↓
https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action
Creating a Docker container action - GitHub Docs
Introduction In this guide, you'll learn about the basic components needed to create and use a packaged Docker container action. To focus this guide on the components needed to package the action, the functionality of the action's code is minimal. The acti
docs.github.com
ktlint로 체크해서 오류가 없는지 검사 후 Docker 이미지를 빌드한다.
# This is a basic workflow to help you get started with Actions name: Workflow # Controls when the workflow will run on: # Triggers the workflow on push or pull request events but only for the "main" branch push: branches: [ "main" ] pull_request: branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Set up JDK 11 uses: actions/setup-java@v1 with: java-version: '11' distribution: 'adopt' - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Run Kotlin Linter run: ./gradlew ktlintCheck - name: Build with Gradle run: ./gradlew build - name: Docker build run: | docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} docker build -t spring-cicd . docker tag spring-cicd ${{ secrets.DOCKER_USERNAME }}/spring-cicd:${GITHUB_SHA::7} docker push ${{ secrets.DOCKER_USERNAME }}/spring-cicd:${GITHUB_SHA::7}
main 브랜치에 push 해주면 다음과 같이 잘 실행된다.
도커 Remote repository에서 확인하면 이미지가 잘 들어온 것을 확인할 수 있다.
CD
이제 올라온 이미지를 가지고 ec2에 자동적으로 배포가 이루어지도록 해보자. 먼저 ec2 생성하고 보안규칙은 22 포트와 80(docker 접속)포트를 열어준다.
$ ssh -i [pem키].pem ubuntu@[ec2 public IP] ## 먼저 도커를 설치해준다. $ sudo apt-get update && \ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \ sudo apt-key fingerprint 0EBFCD88 && \ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \ sudo apt-get update && \ sudo apt-get install -y docker-ce && \ sudo usermod -aG docker [설정할 사용자 이름] && \ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ sudo chmod +x /usr/local/bin/docker-compose && \ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose ## 설치된 도커 버전 확인 $ docker --version Docker version 20.10.21, build baeda1f
이제 ssh 키를 이용해서 github action이 ec2 서버에 접근해서 배포를 할 수 있도록 설정해주자. ec2 서버에서 먼저 ssh 키를 생성해준다.
$ ssh-keygen -t rsa -b 4096 -C [사용자이메일] -f [키 이름(여기서는 spring-cicd)] SHA256:Btg5wteZJaErAtLqlFiUqmbKimJ16+71ufU5Mo/vyPY The key's randomart image is: +---[RSA 4096]----+ | .. o.. | | o.. o + = | |o.o + B + | |++. o + | |+o. . . S | |+o o o . | |=.. . .. . | |+o .. . +++.. | |* ++ +o+BE. | +----[SHA256]-----+ ## 키 생성 확인 $ ls spring-cicd spring-cicd.pub
생성된 공개키를 authorized_keys에 추가해준다. ( ssh 키로 접속이 가능하도록)
$ cat spring-cicd.pub //나오는 내용 복사 ## authorized_keys에 위의 복사 $ cd ~/.ssh $ vi authorized_keys
이제 개인키는 github action secrets에 등록해주자.
$ cat spring-cicd // 복사할 private key
도커와 같이 secrets에 private 키를 등록해준다.
이제 모든 설정이 완료되었으니 github action에 다음과 같이 CD 부분을 추가해준다.
↓
https://github.com/marketplace/actions/docker-metadata-action
Docker Metadata action - GitHub Marketplace
GitHub Action to extract metadata (tags, labels) for Docker
github.com
# This is a basic workflow to help you get started with Actions name: Workflow # Controls when the workflow will run on: # Triggers the workflow on push or pull request events but only for the "main" branch push: branches: [ "main" ] pull_request: branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Set up JDK 11 uses: actions/setup-java@v1 with: java-version: '11' distribution: 'adopt' - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Run Kotlin Linter run: ./gradlew ktlintCheck - name: Build with Gradle run: ./gradlew build - name: Docker build run: | docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} docker build -t spring-cicd . docker tag spring-cicd ${{ secrets.DOCKER_USERNAME }}/spring-cicd:${GITHUB_SHA::7} docker push ${{ secrets.DOCKER_USERNAME }}/spring-cicd:${GITHUB_SHA::7} - name: Deploy uses: appleboy/ssh-action@master with: host: [ec2~로 시작하는 ec2 서버명] username: [위에서 설정한 docker 사용자 이름] key: ${{ secrets.SSH_PRIVATE_KEY }} envs: GITHUB_SHA script: | docker pull ${{ secrets.DOCKER_USERNAME }}/spring-cicd:${GITHUB_SHA::7} docker tag ${{ secrets.DOCKER_USERNAME }}/spring-cicd:${GITHUB_SHA::7} spring-cicd docker stop server // 미리 올라가있는 서버가 존재하면 일단 내리고 docker run -d --rm --name server -p 80:8080 spring-cicd // 다시 실행
빌드 및 배포가 잘 성공한다.
ec2 서버에서 확인해보자. 컨테이너가 잘 실행되는 것을 확인할 수 있다.
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fe4a81a25afb spring-cicd "java -jar /app.jar" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp, :::80->8080/tcp server
여기서 권한 오류가 발생한다면 다음과 같이 해준다.
$ docker ps -a Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1": dial unix /var/run/docker.sock: connect: permission denied $ sudo usermod -aG docker [위에서 생성한 사용자 이름] $ newgrp docker
로그를 확인해보면 잘 실행되는 것을 확인할 수 있다.
http://[ec2 public IP]:80으로 접속해도 잘 되는 것을 확인할 수 있다. 완성 ! ✨
(참고한 사이트)
https://seulcode.tistory.com/557
도커 권한문제 해결하기: "Got permission denied while trying to connect to the Docker daemon socket"
Got permission denied issue in linux linux에서 root 권한이 아닌 상태로 docker를 실행하면 권한 문제가 발생할 수 있다. [linux@localhost ]$ docker ps Got permission denied while trying to connect to the Docker daemon socket at unix:/
seulcode.tistory.com
https://umanking.github.io/2021/07/11/spring-boot-docker-starter/
Spring Boot, Dockerfile로 이미지 생성, 배포하기
SpringBoot프로젝트, Dockerfile을 만들어서 이미지를 생성하고 배포해보자!
umanking.github.io
https://itcoin.tistory.com/685
Github actions를 이용한 CICD - 2
지난 깃헙액션 포스팅에서 깃헙액션을 이용해 빌드 자동화를 마쳤습니다. 이번 포스팅에서는 도커를 사용해서 배포 준비를 할 것입니다. 도커를 사용한다면 어디에서 동일한 환경의 배포를 할
itcoin.tistory.com
Github Action을 이용한 CI구축하기
이것저것 공부하다, 블로그 글을 너무 소홀히 한 것 같아 다시 열심히 정리하려고 다짐했습니다.
wjdqlsdlsp.github.io
https://goodgid.github.io/Github-Action-CI-CD-Workflows/👍
Github Action으로 CI/CD 구축하기 - 4편 : deploy.yaml 분석
Index
goodgid.github.io
'GIT' 카테고리의 다른 글
github으로 maven repo 만들기 (5) 2024.10.09 맥에서 Git Error permission denied to <Unknown User> 문제 발생시 (0) 2022.11.15 Github Actions (0) 2022.11.03 git 기능 구현을 다른 브랜치에서 작성했을 때 (0) 2022.01.25 Git Commit Convention (0) 2021.12.14