※ 참고
젠킨스를 사용하면서 메모리 사용량을 조회해 보니 컨테이너 실행만으로 600MB의 메모리를 사용하고 빌드 시 1GB 가까이 메모리를 사용합니다.
저는 아주 간단한 프로젝트를 빌드 했지만 프로젝트의 규모가 커질수록 메모리 사용량은 늘어날 것으로 보입니다. 이 점 서버 구성할 때 참고하세요!
(AWS에서 프리 티어 플랜을 사용할 경우 작동이 원활하지 않을 수 있습니다.)
깃허브 프로필 > settings
왼쪽 제일 하단의 Developer settings
선택
Personal access tokens -> Tokens(classic)
토큰명 입력 후, 원하는 기한을 선택합니다.
저는 만료일 없음을 선택하였습니다.
repo
, admin:repo_hook
권한 선택
repo
권한은 리포지토리의 정보와 커밋 내역을 읽고 쓰는 등의 권한 입니다.
admin:repo_hook
권한은 네 번째 게시글에서 레파지토리에 푸시가 발생하면 자동으로 젠킨스가 그것을 감지할 수 있게끔 해주기 위한 권한입니다.
생성된 토큰 값 확인
토큰 값은 해당 화면을 넘어간 이후에는 다시 확인 할 수 없습니다. 꼭 다른 곳에 메모해두시고 노출되지 않게 주의해주세요.
만약 토큰 값을 잊어버리셨다면 기존 토큰 삭제 후 재생성해야합니다.
젠킨스 페이지로 돌아와서 젠킨스 관리 > 시스템 설정
Credentials 창이 하나 나오게 되는데
Domain
→ 유지
Kind
→ Secret text
Scope
→ 유지
Secret
→ Github에서 발급받은 토큰 값
ID
→ Github ID
Credentials 드롭박스를 누르면 아까 입력한 Credentials가 보입니다.
선택후 Test connection 진행
젠킨스 대시보드에서 새로운 Item
을 선택합니다.
이름 입력 > Pipeline 선택 > Ok
4.1 Do not allow the pipeline to resume if the controller restarts(파이프라인 충돌 방지 옵션) 체크
Do not allow the pipeline to resume if the controller restarts 항목 외에는 체크하는 항목 없습니다.
다음 단계에서 필요한 항목은 다음 게시글에서 설명하겠습니다
지금은 Do not allow the pipeline to resume if the controller restarts항목만 체크해주세요
파이프라인 스크립트 작성
my_container_name과 my_image_name은 원하시는 이름으로 대체하시면 됩니다.
하지만 각각의 my_container_name과 my_image_name이 들어있는 위치는 맞춰주셔야 됩니다.
아래에 파이프 코드가 있습니다 !
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: '브랜치명', url: '깃 저장소.git 링크'
}
}
stage('Build') {
steps {
sh 'chmod +x ./gradlew'
sh './gradlew build'
}
}
stage('Dockerize') {
steps {
sh '''
docker stop my_container_name || true
docker rm my_container_name || true
docker rmi my_image_name || true
docker build -t my_image_name .
'''
}
}
stage('Deploy') {
steps {
sh 'docker run -d --name my_container_name -p 8080:8080 my_image_name'
}
}
}
}
Dockerize Stage
docker stop, docker rm, docker rmi 명령어의 || true 부분은 해당 명령어들이 실패하더라도 파이프라인이 중지되지 않도록 하는 용도입니다. 실패 시에 계속 진행하길 원한다면 이 방식으로 처리하는 것이 괜찮습니다.
Docker Build
docker build -t imageName .에서 .은 Dockerfile이 있는 디렉토리를 가리킵니다. Dockerfile이 파이프라인이 실행되는 워크스페이스에 있다면 아무 문제 없겠지만, 그렇지 않다면 경로를 조정해야 합니다.
Deploy Stage
docker run 명령어를 사용하여 컨테이너를 실행합니다. 여기서는 포트 매핑 등이 필요에 따라 조정해야 할 수 있습니다.
파이프라인이 기본적인 빌드, 도커 이미지 빌드, 배포 단계를 포함하고 있으며, 필요에 따라 추가적인 단계를 추가하여 확장할 수 있을 것입니다. 작성된 파이프라인을 테스트하고 필요에 따라 수정하면 됩니다.
실행 순서
Pipeline 빌드버튼 클릭 → Pipeline script시작 → stage('Checkout')에 정의된 깃 레파지토리의 브랜치 소스를 가져옵니다.
→ stage('build') 에서 sh명령어 './gradlew build' 에 의해 해당 레파지토리 소스를 그래들로 빌드를 실행합니다. ('./gradlew' 는 현재 경로에서의 gradlew파일을 의미합니다. Checkout단계에서 깃 레파지토리 소스를 가져왔기때문에 './' 경로는 레파지토리의 최상단을 의미합니다)
→ stage('Dockerize') 에선 sh 명령어로
① docker stop my_container_name || true
② docker rm my_container_name || true
③ docker rmi my_image_name || true
④ docker build -t my_image_name . ←마지막에 .(점)이 있으니 꼭 적어주세요.
네가지를 실행합니다.
①은 이름이 my_container_name인 컨테이너가 실행중이라면 해당 컨테이너를 중지시킵니다. 중지시킬 컨테이너가 없다면 "|| true" 에 의해서 다음 명령어로 진행됩니다.
②는 중지시킨 컨테이너를 삭제합니다.
③은 이름이 my_image_name인 이미지 파일을 삭제합니다.
(여기까지 진행이 되면 기존에 존재하던 프로젝트 정보는 모두 삭제돼서 없어집니다. 그렇기 때문에 빌드를 여러번 실행하더라도 데이터가 계속 쌓이지 않습니다.)
④는 이제 새롭게 my_image_name의 이름으로 이미지를 빌드합니다. 이미지파일은 Dockerfile을 기준으로 빌드되는데, 마지막에 . 을 찍었기때문에 도커는 현재 디렉토리에서 Dockerfile을 찾습니다. (위에서 말했듯이 현재 디렉토리는 깃 레파지토리의 최상위 경로입니다.)
다만, 주의할 점은 Docker 빌드 단계에서 현재 디렉토리에서 Dockerfile을 찾는데, 이는 Jenkins 실행 환경에서 해당 파이프라인이 실행되는 경로를 기준으로 합니다. 따라서 Jenkins에서 실행되는 파이프라인이 Jenkins 워크스페이스 내에 위치하고, Dockerfile도 Jenkins 워크스페이스 내에 있다면 문제 없이 찾아갈 것입니다.
만약 Jenkins 워크스페이스 외부에 Dockerfile이 있다면 해당 경로로 이동하여 Dockerfile을 찾을 수 있도록 경로를 조정해야 할 것입니다.
제 프로젝트의 repository는 Private 상태입니다. 그래서 저장소 접근에 문제가 생기더라구요. 토큰 값으로 저장소를 접근할 수 없는 문제였습니다.
여러 과정을 거쳐 해결했으나 아래 방법을 거치니 해결되었습니다.
가장 먼저 토큰을 재생성 해야합니다 !
Fine-grained tokens
를 선택합니다.
Resource owner
를 선택해주시고 !
(저의 경우는 organization을 선택했습니다.)
Select repositories
를 선택해주세요 !
그리고 아래처럼 권한을 부여하고 토큰을 생성해주시면 됩니다 !
이후 Dashboard → Jenkins 관리 → System으로 들어오셔서 Add → Jenkins를 선택해주시고
사진 참고하시면서 Password를 생성한 토큰 값을 넣어주시고 아래 스크립트에
생성한 Credentials 아이디
을 넣어주시면 됩니다.
생성된 Credentials
는 아래 사진을 참고해서 확인하실 수 있습니다 !
수정된 파이프라인
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: '브렌치명',
credentialsId: '생성한 Credentials 아이디',
url: '깃허브 주소.git'
}
}
stage('Build') {
steps {
sh 'chmod +x ./gradlew'
sh './gradlew build'
}
}
stage('Dockerize') {
steps {
sh '''
docker stop 컨테이너명 || true
docker rm e컨테이너명 || true
docker rmi 이미지명 || true
docker build -t 이미지명 .
'''
}
}
stage('Deploy') {
steps {
sh 'docker run -d --name 컨테이너명 -p 8080:8080 이미지명'
}
}
}
}