🍪파이프라인 구축 왜 해야 해?
처음에는 직접 EC2에 접속해서 git pull하고 JAR파일을 직접 실행 하다가 코드가 수정 될 때 마다 계속 접속해서 명령어 쳐 주는게 귀찮아서, 쉘 스크립트를 도입해서 반복 작업을 줄이다가 이것도 귀찮아서 git에 push만 하면 자동으로 배포 되게 하기 위해 CI/CD 파이프라인을 구축해서 완전 자동화를 구현 해 볼려고 해
🤖CI/CD 란?
CI는 Continuous Integration 지속적 통합으로 개발자들이 코드를 중앙 저장소에 통합 문제를 최소화하고 코드 변경이 일어날 때 마다 자동으로 빌드 및 테스트가 실행되어 문제가 있는지 즉시 확인할 수 있다.
CD는 Continuous Deployment 지속적 배포로 CI를 통과한 이후 자동으로 운영 서버에 배포 하는 파이프라인 구축을 목적으로 한다.
🐻Github Actions 선택
GitHub Actions는 GitHub 내에서 모든 빌드, 테스트, 배포 작업을 자동화할 수 있고 GitHub 레포지토리와 자연스럽게 통합되어 있어 다른 도구 없이 바로 CI/CD 파이프라인을 구축 할 수 있으며 GitHub Secrets을 활용해 환경변수를 안전하게 관리 할 수 있다는 장점이 있어 GitHub Actions을 선택했어
😱파이프라인 과정
- 개인 브랜치에서 코드 수정
- main브랜치로 PR & Merge
- Github Actions에서 코드 문제 검사 후 빌드, Docker Image 빌드
- Docker 로그인 후 이미지 Docker Hub에 Push
- SSH로 EC2 인스턴스 접속 후 Docker Hub에서 Pull받아 컨테이너 실행
🙊DockerFile 준비
ARG 를 사용하는 이유는 GitHub Actions에서 빌드할 때 환경 변수가 없으면 에러가 나기 때문에 ARG로 환경 변수를 설정하고 GitHub Actions에서 빌드할 때 --build-arg로 값을 주입해줘야 해
FROM openjdk:17-jdk-slim
WORKDIR /app
ARG DB_PASSWORD
ARG DB_URL
ARG DB_USERNAME
ARG JAR_FILE=build/libs/dev-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} dev-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "dev-0.0.1-SNAPSHOT.jar"]
🎃GitHub Actions .yml파일 작성
GitHub Actions 파일 작성 하는 거랑 환경변수는 밑에 내가 따로 "상세하게 작성한 블로그 확인 해 줘"
GitHub Actions
🧐 Github Action란? GitHub Actions은 GitHub에서 제공하는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트) 플랫폼입니다. 🥺 CI/CD 란?반복적인 일 들을 처
imdo714.tistory.com
name: Java CI with Gradle
on:
push:
branches: [ "V1" ]
pull_request:
branches: [ "V1" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
# 1. 코드 체크아웃
- name: Check out code
uses: actions/checkout@v4
# 2. JDK 17 설치
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# 3. 현재 작업 디렉토리 확인
- name: Print working directory
run: pwd
# 4. gradlew 파일 확인
- name: List files in the directory
run: ls -la
# 5. Gradle 캐시 설정
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
# 6. Gradle Wrapper 실행 권한 추가
- name: Set executable permission for gradlew
run: chmod +x ./gradlew
# 7. Gradle 빌드 및 테스트 실행
- name: Build with Gradle
run: ./gradlew build -x test --no-daemon
# 8. Docker 이미지 빌드
- name: docker image build
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/test-cicd .
- name: docker image build
run: |
docker build \
--build-arg DB_PASSWORD=${{ secrets.DB_PASSWORD }} \
--build-arg DB_URL=${{ secrets.DB_URL }} \
--build-arg DB_USERNAME=${{ secrets.DB_USERNAME }} \
-t ${{ secrets.DOCKERHUB_USERNAME }}/test-cicd .
# 9. DockerHub 로그인
- name: docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# 10. Docker Hub 이미지 푸시
- name: docker Hub push
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/test-cicd
🐯EC2 추가 부분
GitHub Actions에서 Docker Hub에 이미지를 푸시한 후, SSH를 통해 EC2에 접속하여 컨테이너를 배포하는 스크립트를 실행하는 부분이다. 스크립트 부분을 보면 SSH로 EC2 접속 후 Docker Hub에서 이미지를 Pull받고 기존 컨테이너 멈추고 삭제 후 8080포트로 재 실행하는 코드야
- EC2_HOST 는 EC2 퍼블릭 IP이다.
- EC2_USER 는 EC2 접속할 때 사용하는 사용자 이름이야 나는 Ubuntu를 사용해서 ubuntu로 설정했어
- EC2_SSH_KEY 는 EC2를 생성할 때 .pem 형식의 키 페어를 만들었는 그 키 값이야
# 11. EC2 자동 배포 명령어
- name: SSH to EC2 and deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/test-cicd
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/test-cicd
💣트러블 슈팅
나는 계속 EC2_SSH_KEY 를 입력 했는데 ssh.ParsePrivateKey: ssh: no key found라는 에러가 떴다. 첫 번째 이유는 앞에 띄어쓰기 하나가 있었는데 그거 때문에 에러가 났다. 두 번째는 "인코딩 되어있는 데이터만 넣으면 되는 줄 알고" 위아래 값들을 안 넣었었다.
-----BEGIN RSA PRIVATE KEY-----
(Base64 인코딩된 키 데이터)
-----END RSA PRIVATE KEY-----
👏결과
이제 Git에 Push만 하면 GitHub Actions 가 빌드 테스트 모두 통과하고 EC2에 접속해 자동으로 컨테이너 실행까지 해 주어 아주 편하게 자동 배포까지 해 주게 되었다.
'CICD' 카테고리의 다른 글
GitHub Actions (0) | 2024.11.16 |
---|---|
Docker & Docker Hub (1) | 2024.11.16 |