환경
- Ubuntu 20.04 Server
순서
- 스프링부트 프로젝트를 Github에 Commit
- Github의 Webhook 기능을 이용해 Jenkins에 자동으로 trigger 유발
- trigger된 Jenkins에서 Github Clone후 Dockerfile을 통해 Docker Image 생성
- Docker Image를 Docker Hub에 Push
- SSH Agent를 통해 원격 서버에서 Docker Image를 Pull 한 후 Run으로 실행
이전 글에서 설명했던 부분은 전부 넘어가도록 하겠습니다.
아래 내용은 프로젝트를 Docker Image를 만드는 데서부터 시작합니다.
왜 jar로 하면 될 일을 굳이 Docker를 쓸까요?
Docker를 이용하면 어떤 운영체제든지 쉽게 컨테이너 실행이 가능하며 가벼워진다는 장점이 있습니다.
Dockerfile 작성
FROM openjdk:11
ARG JAR_FILE=./build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Clone 받아온 프로젝트 루트 경로에 Dockerfile을 만들어줍니다.
해당 Dockerfile을 이용해 Docker Image를 만들게 됩니다.
Dockerfile을 루트 경로에 수동으로 만들어도 되지만 추후 관리를 위해 Github 소스에 추가해서 관리하는 것이 좋습니다.
마찬가지로 JenkinsFile 역시 Github 소스 내에 관리할 수 있습니다.
아래와 같이 Pipeline Script from SCM을 선택하면 Github내에서 모든 소스를 관리할 수 있습니다.
Docker Image 생성 후 Push
파이프라인을 만들기전에 docker Hub 계정을 만들어주고 해당 계정에 대한 Credential을 등록해줘야 합니다.
그리고 docker hub에서 레파지토리를 하나 만들어줘야 합니다.
pipeline {
agent any
environment {
DOCKERHUB_CREDENTIALS = credentials('dockerhub') // jenkins에 등록해 놓은 docker hub credentials 이름
}
stages {
stage('github Clone') {
steps {
git credentialsId: 'stir084', url: 'https://github.com/stir084/JenkinsStudy.git'
}
}
stage('Bulid Gradle') {
steps {
sh 'echo "Bulid Gradle Start"'
dir('.') {
sh """
chmod +x gradlew
./gradlew clean build --exclude-task test
"""
}
}
}
stage('Bulid Docker') {
steps {
script {
app = docker.build repository + ":$BUILD_NUMBER"
}
}
}
stage('Login'){
steps{
sh 'echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin' // docker hub 로그인
}
}
stage('Deploy our image') {
steps {
script {
sh 'docker push 아이디/레파지토리명:$BUILD_NUMBER'
}
}
}
도커 이미지를 빌드하고 배포하는 데까지 3단계에 걸쳐서 작성됩니다.
Scripted Pipeline을 이용하면 로그인과 이미지 배포를 한번에 할 수 있었으나 해당 방식은 완전히 막혔습니다.
도커버전 17이후부턴 비대화식으로 docker 로그인 명령을 실행하려면 --password-stdinSTDIN을 통해 암호를 제공하도록 플래그를 설정해야 합니다.
그래서 Declarative Pipeline으로 위와 같이 3단계에 걸쳐서 작성해줘야합니다.
Repository가 "아이디/레파지토리명"이라면 빌드된 이미지의 이름도 "아이디/레파지토리명"으로 만들어져야 Docker Hub에 정확히 Push 됩니다.
Push가 되었다면 Docker Hub에 위와 같이 잘 Push 된걸 확인할 수 있습니다.
SSH Agent를 통해 이미지 배포
이전 글에서는 jar파일을 전달해야 했기 때문에 Publish Over SSH 플러그인을 사용했습니다.
Docker도 다중 서버 환경을 구축할 수가 있는데 이번엔 전달할 파일이 없고 단순히 원격 서버에서 Docker Hub에 올라간 Image를 내려 받아야 하기 때문에 SSH Agent를 이용해 명령문을 전달해야 합니다.
SSH Agent도 역시 Credential을 등록해줘야하는데 Publish Over SSH에서 생성했었던 방식으로 원격 서버에 RSA 키를 생성해서 사용하면 됩니다.
stage('Cleaning up') {
steps {
sh "docker rmi $repository:$BUILD_NUMBER" // docker image 제거
}
}
stage('Docker Pull And Run') {
steps {
sshagent (credentials: ['sshAgentKey']) {
sh "ssh -o StrictHostKeyChecking=no 원격서버Username@원격서버Ip 'docker pull 아이디/레파지토리명:$BUILD_NUMBER'"
sh "ssh -o StrictHostKeyChecking=no 원격서버Username@원격서버Ip 'docker rm -f container_app'"
sh "ssh -o StrictHostKeyChecking=no 원격서버Username@원격서버Ip 'docker run -d --name container_app -p 8080:8080 아이디/레파지토리명:$BUILD_NUMBER'"
}
}
}
위의 모든 단계를 통과 하면 Docker Image를 통해 배포가 마무리 되었습니다.
번외 - Docker Compose
Docker Run이 아니라 Docker Compose를 통해서 실행해보고 싶다면 아래와 같이 docker-compose.yml 파일을 만듭니다
version: "3"
services:
app:
build:
context: ./
dockerfile: Dockerfile
container_name: container_app
restart: always
ports:
- "8080:8080"
그리고 docker-compose up -d를 통해 실행하면 docker-compose를 통해 실행할 수 있습니다.
'🛠️ CI & CD' 카테고리의 다른 글
Harbor 용량 관리 및 트러블 슈팅 (0) | 2023.12.21 |
---|---|
스프링부트 + Github + Jenkins / CI & CD 연습하기 (1) (5) | 2022.10.03 |
Jenkins Blue Ocean 소개 및 주관적인 단점 3가지 (1) | 2022.09.26 |
Jenkins 에서 SSH 접속 시 sudo 권한 사용 (0) | 2022.09.26 |
도커에 젠킨스를 설치하는 것에 대한 장점과 단점 (0) | 2022.09.22 |