[CI/CD] GitHub, Jenkins, Docker를 활용한 CI/CD 환경 구축 - 4

chrkb1569·2024년 1월 6일
0

개인 프로젝트

목록 보기
28/28

지난 시간에는 Jenkins 파일을 통하여 Docker 이미지를 빌드하고 이를 push하도록 설정하였습니다.

오늘은 Application Server 인스턴스를 생성한 뒤, 이를 Jenkins Server와 연동하여 자동화된 CI/CD 환경을 구축해보겠습니다.

Application Server 구축

Swapping

Application Server에서도 Docker를 사용할 예정이지만, 현재로써는 메모리가 부족하기 때문에 메모리 문제를 해결하기 위해 Swapping을 사용하였습니다.

Swapping은 AWS 공식 문서를 참고하였습니다.

https://repost.aws/ko/knowledge-center/ec2-memory-swap-file

Docker 설치

Docker 설치는 Docker 공식 문서를 참고하여 설치하였습니다.

https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

Plugin 설치

Jenkins에서 빌드가 정상적으로 완료되었다면, jar 파일을 Application Server에 SSH 통신으로 전송해야하기 때문에 별도의 Plugin들을 설치해주겠습니다.

Jenkins 관리 -> Plugins 이동

Public Over SSH, Post build task 플러그인 설치

SSH 설정

Jenkins 관리 -> System 이동
하단에 Public Over SSH 옵션으로 이동

SSH Server 옵션을 선택한뒤,

다음처럼 Application Server의 정보를 입력

하단에 고급 옵션으로 SSH 통신에 사용할 key의 정보를 등록할 수 있는데, Use password authentication, or use a different key 옵션을 선택한 뒤, pem 키 정보를 기입한 뒤 저장합니다.

Jenkins 파일 수정

pipeline {
    agent any

    stages {
        stage('Clone Repository') {
            steps {
                git branch: 'main', url: "https://github.com/chrkb1569/DevOps-Practice"
            }
        }

        stage('Build Project') {
            steps {
                sh './gradlew clean build'
            }
        }

        stage('Docker Login') {
            steps {
                sh 'echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin'
            }
        }

        stage('Build Docker Image') {
            steps {
                sh 'docker build -t chrkb1569/jenkins:test .'
            }
        }

        stage('Push Docker Image') {
            steps {
                sh 'docker push chrkb1569/jenkins:test'
            }
        }

        stage('Deploy') {
            steps {
                sh 'ssh -o StrictHostKeyChecking=no ubuntu@$APPLICATION_SERVER'
                sh 'scp $JAR_FILE_PATH ubuntu@$APPLICATION_SERVER:/home/ubuntu/chrkb1569'
                sh 'scp $SCRIPT_FILE_PATH ubuntu@$APPLICATION_SERVER:/home/ubuntu/chrkb1569'
                sh 'ssh ubuntu@$APPL![](https://velog.velcdn.com/images/chrkb1569/post/6a8a3e5f-e017-471c-8b3e-eecb75ab7a15/image.png)
ICATION_SERVER "sudo chmod 777 /home/ubuntu/chrkb1569/DockerDeploy.sh"'
                sh 'ssh ubuntu@$APPLICATION_SERVER "sudo chmod 777 /home/ubuntu/chrkb1569/*.jar"'
                sh 'ssh ubuntu@$APPLICATION_SERVER "/home/ubuntu/chrkb1569/DockerDeploy.sh"'
            }
        }
    }
}

ssh 통신을 통한 원격 배포를 추가하였습니다.

ssh 통신으로 jar 파일과 쉘 스크립트 파일을 전달한 뒤, 이를 실행하여 Application Server에서 Docker 이미지가 동작하도록 설계하였습니다.

JAR_FILE_PATH -> jar 파일이 존재하는 위치
APPLICATION_SERVER -> Application Server의 IP주소
SCRIPT_FILE_PATH -> 스크립트 파일이 존재하는 위치

빌드 결과

빌드는 성공적으로 이루어졌으나, 실행한 컨테이너가 바로 죽는 현상이 발생

$ docker logs {컨테이너 이름}

다음 명령어를 통하여 컨테이너의 로그 확인

데이터베이스 연결에 필요한 환경변수가 주어지지 않아 이러한 오류가 발생하였습니다.

지난 번에는 쉘 스크립트 파일에 직접적으로 환경 변수를 입력해주었지만, 오늘은 .env 파일을 통하여 환경 변수를 주입해주겠습니다.

# vim .env

다음 명령어를 통하여 환경 변수를 저장하는 파일을 생성한 뒤, Docker가 환경 변수를 참조하여 명령어를 실행할 수 있도록 다음처럼 수정해주었습니다.

수정된 쉘 스크립트 파일

#!/bin/bash

DOCKER_REPOSITORY=chrkb1569/jenkins
DOCKER_TAG=test

echo "> 현재 실행 중인 Docker Container ID 확인"
DOCKER_ID=$(docker ps -aqf "name=Jenkins")

echo "> 현재 실행 중인 Docker Container ID == $DOCKER_ID"
if [ -z "$DOCKER_ID" ]; then
  echo "> 현재 실행 중인 Docker Container가 존재하지 않습니다."
else
  echo "> 현재 실행 중인 컨테이너를 종료하겠습니다."
  docker stop $DOCKER_ID
  docker rm $DOCKER_ID
  sleep 10
fi

echo "> 실행 중인 Docker Container를 종료하였습니다."

echo "> Docker Image를 삭제하겠습니다."
docker rmi $DOCKER_REPOSITORY:$DOCKER_TAG

echo "> Docker Image를 가져옵니다."
docker pull $DOCKER_REPOSITORY:$DOCKER_TAG

echo "> Docker Image를 실행합니다."
docker run -d -p 8080:8080 --name Jenkins --env-file /home/ubuntu/chrkb1569/.env $DOCKER_REPOSITORY:$DOCKER_TAG

수정된 Dockerfile

FROM openjdk:17-oracle

VOLUME /tmp

ARG JAR_FILE=/build/libs/*.jar

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["nohup", "java", "-jar", "app.jar", "-dDB_URL=$URL", "-dDB_USERNAME=$USERNAME", "-dDB_PASSWORD=$PASSWORD", "&"]

필요한 환경 변수 설정 이후, 다시 실행

다음처럼 빌드가 완료된 이후, 정상적으로 배포가 완료됨을 확인할 수 있었습니다.

Reference

https://ko.linux-console.net/?p=7702

0개의 댓글