Jenkins 빌드, DockerHub push 후 배포 서버에서 application 실행 방법

청포도봉봉이·2023년 10월 10일
1

AWS

목록 보기
9/14
post-thumbnail

🚩 현 상황 및 해야할 것

현재까지 구현된 상태는 GitHub repository에서 push를 하면 jenkins에서 자동으로 감지하여 빌드 실행이다.

앞으로 해야될 과정은
1. jenkins에서 gradle로 빌드한 jar 파일을 docker image로 빌드하여 Docker Hub에서 push
2. Docker Hub Repository에 push가 완료된 후 ssh를 통해 배포 서버에서 Docker Hub image를 pull 받은 후 도커 이미지를 실행하여 application 구동을 확인 하는 것이다.

따라서 필요한 것은
1. Docker Hub 계정 생성 및 Repository 생성
2. jenkins 서버와 배포 서버의 ssh 연결 과정
3. DockerFile 작성 및 Docker 빌드 스크립트 작성

이 정도가 있다.

🚩 Docker Hub

👉 Docker Hub 계정 생성

https://hub.docker.com/ 에서 회원가입을 해준다.

👉 Docker Hub Repository 생성

생성된 Repository에 가보면

이렇게 push 하는 명령어의 예시가 있다. 이걸 사용할 것이다.




🚩 DockerFile 작성

Root 디렉토리에 DockerFile을 만들어주고 아래와 같이 작성한다.

# 베이스 이미지 선택
FROM amazoncorretto:11

# /deploy 디렉터리 생성
RUN mkdir /deploy

# JAR 파일 변수 지정
ARG JAR_FILE=build/libs/till.back-0.0.1-SNAPSHOT.jar 

# deploy 폴더로 jar 파일 복사
ADD ${JAR_FILE} /deploy/toy-mini-blog-back.jar

# 서버 포트 설정
EXPOSE 8081

# 환경 변수로 프로파일 설정
ENV SPRING_PROFILES_ACTIVE=prod

# jar 파일 실행
ENTRYPOINT ["java", "-jar", "/deploy/toy-mini-blog-back.jar"]

DockerFile작성하면 DockerFile을 읽어 Docker image를 빌드한다.




🚩 Jenkins 설정( Docker Image push )

구성으로 간 후 Build Steps 설정에

Execute Shell을 추가한 후

echo docker login
docker login -u '도커 허브 ID' -p '도커 허브 PW' docker.io

echo now path
pwd

echo docker image build
docker build -t pak0426/toy-mini-blog-back:latest .

echo docker image push
docker push pak0426/toy-mini-blog-back:latest

위와 같이 작성해준다.

그렇다면 빌드를 하고 난 후에 root 디렉토리에서 Dockerfile을 읽어드려 script를 실행하는 걸 확인 할 수 있다.

/var/jenkins_home/workspace/toy-mini-blog-back
위의 root 디렉토리는 jenkins 컨테이너 접속 후의 경로이다.




🚩 배포 서버와의 ssh 연결 설정


👉 ssh key 생성 및 연결

ssh-keygen -t rsa -C "키명칭" -m PEM -P "" -f /root/.ssh/"키명칭"

ex) ssh-keygen -t rsa -C "mykey" -m PEM -P "" -f /root/.ssh/mykey

위와 같은 key jenkins 서버에서 생성한다.

그리고 난 뒤에

sudo cat /root/.ssh/[키명칭].pub

생성된 ssh 키를

복사한다.

복사 후 배포 서버로 가서

cd .ssh
cat authorized_keys
sudo vi authorized_keys

기존에 key 내용이 들어있을텐데 아래에 추가해준다.

👉 Publish Over SSH


👉 플러그인 설치

publish over ssh을 설치 해준다.

위와 같이 설치하면 된다.


👉 플러그인 설정

Dashboard -> jenkins 관리 -> system 으로 이동

하단으로 이동하면 Pushlish over SSH 설정 영역이 생긴걸 확인할 수 있다.

Passpahrase에 연결할 SSH 서버 계정 비밀번호 입력

추가 후

Name : 내가 칭할 서버 이름
HostName : 접속하려는 서버의 IP 주소
Username : 접속하려는 서버의 로그인 아이디

Test Configuration 클릭 후 Success가 뜨면 성공이다.




🚩 Jenkins 설정( Docker Image pull )

published over ssh 설정 후 본인의 project의 설정에 가준다.

Build Steps에서 add를 클릭 후

Send files or execute commands over SSH 클릭

내가 만들었던 배포 서버를 선택 후

Exec command에 ssh 연결 후에 배포 서버에서 실행할 스크립트를 작성한다.

# 이미지 이름과 태그
IMAGE_NAME="pak0426/toy-mini-blog-back"
TAG="latest"

# 새로운 이미지 pull
docker pull $IMAGE_NAME:$TAG

# 기존 컨테이너 stop 및 remove
docker stop toy-mini-blog-back
docker rm toy-mini-blog-back

# 새로운 이미지로 컨테이너 시작
docker run -d --name toy-mini-blog-back -p 8081:8081 $IMAGE_NAME:$TAG

# 기존 도커 이미지 삭제
no_tag_image_ids=$(docker images -f "dangling=true" -q)

if [ -z "$no_tag_image_ids" ]; then
  echo "삭제할 이미지가 없습니다."
else
  # 각 이미지 ID에 대해 순회하며 삭제하기
  for image_id in $no_tag_image_ids; do
    docker rmi $image_id
    echo "이미지 $image_id 삭제 완료"
  done
fi
  1. IMAGE_NAME="pak0426/toy-mini-blog-back": 환경 변수 IMAGE_NAME에 Docker 이미지 이름을 설정한다. 여기서는 "pak0426/toy-mini-blog-back"으로 설정되어 있다.

  2. TAG="latest": 환경 변수 TAG에 Docker 이미지의 태그를 설정한다. 여기서는 "latest"로 설정되어 있다.

  3. docker pull $IMAGE_NAME:$TAG: 새로운 이미지를 Docker Hub에서 가져온다. $IMAGE_NAME:$TAG는 이전 단계에서 정의된 이미지 이름과 태그를 사용하여 특정 버전의 이미지를 가져온다.

  4. docker stop toy-mini-blog-back: 기존에 실행 중인 도커 컨테이너인 "toy-mini-blog-back"을 정지시킨다.

  5. docker rm toy-mini-blog-back: 기존에 정지된 도커 컨테이너인 "toy-mini-blog-back"을 삭제한다.

  6. docker run -d --name toy-mini-blog-back -p 8081:8081 $IMAGE_NAME:$TAG: 새로운 이미지로 컨테이너를 시작한다.

    • -d 옵션은 컨테이너를 백그라운드에서 실행하도록 지정한다.
    • --name toy-mini-blog-back은 컨테이너의 이름을 "toy-mini-blog-back"으로 지정한다.
    • -p 8081:8081은 호스트의 8081번 포트와 컨테이너 내부의 8081번 포트를 매핑시켜준다.
    • $IMAGE_NAME:$TAG는 이전 단계에서 정의된 이미지 이름과 태그를 사용하여 해당 버전의 이미지로 컨테이너를 생성한다.
  7. no_tag_image_ids=$(docker images -f "dangling=true" -q): dangling 상태인(태그가 없는) 도커 이미지들의 ID 목록을 가져와서 변수에 할당한다.

  8. [ -z "$no_tag_image_ids" ]: $no_tag_image_ids가 비어있다면(즉, dangling 상태인 도커 이미지가 없다면) 다음 라인으로 넘어간다.

  9. [...] for image_id in $no_tag_image_ids; do ... done: dangling 상태인 각 도커 이미지 ID에 대해 반복문을 실행하여 삭제 작업을 수행한다.

    • docker rmi $image_id: 주어진 $image_id에 해당하는 도커 이미지(ID)를 삭제한다.
    • "이미지 $image_id 삭제 완료": 각 삭제 작업 후 해당 메시지가 출력된다.

따라서, 위 스크립트는 주어진 Docker Hub 저장소에서 새로운 버전의 이미지를 가져오고, 기존 컨테이너와 관련된 작업들(stop 및 remove)을 수행한 후, 새로운 버전으로 업데이트된 컨테이너를 시작하며, 마친 후 dangling 상태인 도커 이미지들 중 하나도 남아있다면 순회하며 모두 삭제하는 역할을 한다.




이렇게 설정하고 Jenkins로 빌드를 수행한다면

docker images와 container를 확인 할 수 있을 것이다.


참고 링크

[CI/CD] Jenkins 를 이용한 Docker 컨테이너 기반 애플리케이션 배포 자동화

profile
서버 백엔드 개발자

0개의 댓글