현재까지 구현된 상태는 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 빌드 스크립트 작성
이 정도가 있다.
https://hub.docker.com/ 에서 회원가입을 해준다.
생성된 Repository에 가보면
이렇게 push 하는 명령어의 예시가 있다. 이걸 사용할 것이다.
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를 빌드한다.
구성으로 간 후 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-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
을 설치 해준다.
위와 같이 설치하면 된다.
Dashboard -> jenkins 관리 -> system
으로 이동
하단으로 이동하면 Pushlish over SSH 설정 영역이 생긴걸 확인할 수 있다.
Passpahrase
에 연결할 SSH 서버 계정 비밀번호 입력
추가 후
Name : 내가 칭할 서버 이름
HostName : 접속하려는 서버의 IP 주소
Username : 접속하려는 서버의 로그인 아이디
Test Configuration 클릭 후 Success
가 뜨면 성공이다.
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
IMAGE_NAME="pak0426/toy-mini-blog-back"
: 환경 변수 IMAGE_NAME
에 Docker 이미지 이름을 설정한다. 여기서는 "pak0426/toy-mini-blog-back"으로 설정되어 있다.
TAG="latest"
: 환경 변수 TAG
에 Docker 이미지의 태그를 설정한다. 여기서는 "latest"로 설정되어 있다.
docker pull $IMAGE_NAME:$TAG
: 새로운 이미지를 Docker Hub에서 가져온다. $IMAGE_NAME:$TAG
는 이전 단계에서 정의된 이미지 이름과 태그를 사용하여 특정 버전의 이미지를 가져온다.
docker stop toy-mini-blog-back
: 기존에 실행 중인 도커 컨테이너인 "toy-mini-blog-back"을 정지시킨다.
docker rm toy-mini-blog-back
: 기존에 정지된 도커 컨테이너인 "toy-mini-blog-back"을 삭제한다.
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
는 이전 단계에서 정의된 이미지 이름과 태그를 사용하여 해당 버전의 이미지로 컨테이너를 생성한다.no_tag_image_ids=$(docker images -f "dangling=true" -q)
: dangling 상태인(태그가 없는) 도커 이미지들의 ID 목록을 가져와서 변수에 할당한다.
[ -z "$no_tag_image_ids" ]
: $no_tag_image_ids
가 비어있다면(즉, dangling 상태인 도커 이미지가 없다면) 다음 라인으로 넘어간다.
[...] 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를 확인 할 수 있을 것이다.