본문 바로가기
CS 지식/DevOps

[DevOps] Jenkins로 중단 배포

by ghan2 2025. 8. 3.

https://ghan2.tistory.com/129

 

[Docker] Mysql 도커로 띄우기

https://ghan2.tistory.com/127 [DevOps] Nginx 도커로 띄우기, 왜 Docker인가?https://ghan2.tistory.com/125 [DevOps] Apache와 Spring Boot 연결1. 왜 Apache와 Spring Boot를 연결할까?Spring Boot는 기본적으로 내장 톰캣을 사용한다.

ghan2.tistory.com

 

 

지난 포스팅에서는 개발을 위한 데이터베이스를 띄워봤다.

이제 젠킨스로 무중단 배포 환경을 구성하기 이전에,

중단하고 배포하는 중단배포(?)를 먼저 해보려고 한다.

 

Docker로 Jenkins 설치
mkdir -p /home/jenkins_home

docker run -d \
--name jenkins \
-p 8081:8080 \
-p 50000:50000 \
-v /home/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:lts

 

 

http://서버IP:8081 접속

jenkins 초기 화면

 

아래 경로에서 초기 비밀번호를 가져와서 입력해준다. 

 

sudo docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

 

 

비밀번호 입력시

 

install suggested plugins 를 눌러준다. 

Git, Pipeline, Maven, Gradle, Docker 관련 등 기본적으로 많이 쓰이는 플러그인들이 자동 설치된다. 

나중에 필요 없는 건 끌 수도 있고, 추가 플러그인은 따로 설치할 수 있다. 

 

설치중..

 

Jenkins 계정을 만들고 시작한다!

그 다음엔 Jenkins 컨테이너 안에서 도커를 올릴 것이기 때문에

Docker 명령어가 실행되도록 세팅이 필요하다. 

 

1. Jenkins 컨테이너 안에 docker 명령어 넣기

sudo docker cp $(which docker) jenkins:/usr/bin/docker

: 호스트(우분투)에서 쓰는 docker 실행 파일을 Jenkins 컨테이너 안으로 복사

 

2. Jenkins가 호스트 Docker 데몬에 접근 가능하도록 권한 설정

 

처음 젠킨스를 빌드할 때 해준 설정인데, 

이 부분이 바로 호스트의 Docker 데몬 소켓을 Jenkins 컨테이너 안에 마운트 한 것이다. 

덕분에 컨테이너 안에서 도커 명령어가 호스트의 도커 데몬과 직접 통신이 가능해졌다. 

 

 

-v /var/run/docker.sock:/var/run/docker.sock

 

다만, 처음에 Jenkins 컨테이너 안에 docker 실행파일이 없어서 명령이 안 됐던 거고, docker cp $(which docker) 명령어로 복사해서 해결했다. 

 

이후 도커 명령어를 실행할 수 있도록 권한 세팅을 해준다. 

 

sudo docker exec -u root -it jenkins bash

groupadd docker || true -- 컨테이너 안에 docker 그룹을 만들고 이미 있으면 넘어가도록
usermod -aG docker jenkins -- Jenkins 컨테이너 안의 jenkins 유저를 docker 그룹에 추가.
chown root:docker /var/run/docker.sock -- 소유 그룹을 docker로 변경
chmod 660 /var/run/docker.sock -- 소켓 권한을 rw-rw----로 변경

 

 

Jenkins에서 잡(Job)을 만들어서 docker build / run 실행

 

위와 같이 파이프라인을 작성해주었다.

 

1. Pipeline

pipeline{ ... } 으로 묶어 전체 구조를 정의하고, agent, stages, steps 등을 순서대로 실행한다.

 

2. agent any

빌드 실행 환경을 지정하는 부분이다.

any -> Jenkins에서 설정된 모든 agent(노드)에서 실행 가능하다는 것

예를 들면, 젠킨스 서버 자체에서 실행하거나, 특정 도커 agent에서 실행 가능하다.

 

3. stage('Checkout')

stage('Checkout') { 
	steps { 
    	git branch: 'main', 
        	credentialsId: 'github-token', 
        	url: '...' 
    } 
}
  • GitHub에서 소스 코드를 가져오는 단계
  • branch: 'main' → main 브랜치를 체크아웃.
  • credentialsId: 'github-token' → Jenkins에 저장된 GitHub Personal Access Token을 사용.
  • url → 레포지토리 주소

 

4. stage('Build Jar')

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

 

  • Spring Boot 프로젝트를 빌드해서 실행 가능한 JAR 파일을 만드는 단계
  • ./gradlew clean build:
    • clean → 이전 빌드 파일 삭제 (build 폴더 초기화).
    • build → Gradle 빌드 실행, build/libs/*.jar 생성.
  • 이 단계에서 bootJar가 실행되어야 Dockerfile에서 복사할 jar 파일이 생성됨

 

5. stage('Step Old Container')

stage('Stop Old Container') {
    steps {
        sh '''
        docker stop spring-app || true
        docker rm spring-app || true
        '''
    }
}

 

 

  • 기존에 실행 중인 spring-app 컨테이너를 종료하고 삭제
  • || true → 해당 컨테이너가 없어도 오류 없이 계속 진행

 

6. stage('Build Docker Image')

stage('Build Docker Image') {
    steps {
        sh 'docker build -t spring-app .'
    }
}

 

 

  • 현재 디렉토리(.)에 있는 Dockerfile을 사용해서 새로운 Docker 이미지를 빌드
  • -t spring-app → 이미지 이름을 spring-app으로 지정

 

7. stage('Run New Container')

stage('Run New Container') {
    steps {
        sh '''
        docker run -d \
          --name spring-app \
          -p 8080:8080 \
          spring-app
        '''
    }
}

 

 

  • 새로운 컨테이너를 백그라운드(-d)로 실행
  • --name spring-app → 컨테이너 이름
  • -p 8080:8080 → 호스트 8080 포트를 컨테이너 8080 포트와 연결
  • 이미지 spring-app을 기반으로 실행

** 마지막으로 nginx와 연결해 놓은 상태라 같은 네트워크로 연결하는 설정을 추가했다.

docker network create app-network

docker run -d --name spring-app --network app-network -p 8080:8080 spring-app
docker run -d --name nginx --network app-network -p 80:80 nginx

빌드 성공 !

 

 

시간에 쫓겨서 한거라 부족한 부분이 많아보이지만... 

젠킨스로 자동화 할 수 있다는 건 정말 편해보인다.

 

다시 차근차근 공부해봐야겠다.

충분히 이해한 이후에 무중단 배포도 해보자 !_!