티스토리 뷰
이번 포스팅에서는 Jenkins를 Docker Compose로 설치하고, Github Webhook과 연동하여 CI/CD 파이프라인을 구축하는 전 과정을 정리하였습니다. 실무에서 직접 적용한 사례이며, 필요한 스크립트와 설정도 함께 공유하도록 하겠습니다.
1. 젠킨스 소개
Jenkins는 오픈소스 자동화 서버로, 빌드, 테스트, 배포 등 소프트웨어 개발의 전 과정을 자동화할 수 있습니다. 수많은 플러그인을 통해 다양한 도구 및 환경과 연동할 수 있어 DevOps의 핵심 도구로 자리잡고 있습니다.
2. Docker Compose 로 설치
docker-compose.yml 파일을 통해 젠킨스를 설치할 수 있습니다. 아래 파일을 참조해주세요.
docker-compose.yml
version: '3.8'
services:
### 잰킨스 ###
jenkins:
build:
context: .
dockerfile: Dockerfile
container_name: jenkins-container
user: root
ports:
- "8080:8080"
environment:
- JENKINS_OPTS=--prefix=/jenkins
- TZ=Asia/Seoul
volumes:
- jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /home/workspace/scripts:/scripts
- /home/workspace/api_deploy:/api_deploy
restart: unless-stopped
volumes:
jenkins_home:
- Jenkins LTS 이미지
- 페이지 prefix "/jekins" 사용 -> nginx 로 서빙
- 호스트 볼륨 마운트
- 포트 8080 노출
- docker.sock 바인딩
DockerFile
FROM jenkins/jenkins:lts
USER root
# docker compose plugin 설치
RUN mkdir -p /usr/local/lib/docker/cli-plugins && \
curl -SL https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-linux-x86_64 \
-o /usr/local/lib/docker/cli-plugins/docker-compose && \
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
- 젠킨스 내부에서 Docker compose 명령어 사용
nginx.conf
http {
...
# jenkins
upstream jenkins {
ip_hash;
server 127.0.0.1:8080 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name 도메인orIP;
keepalive_timeout 60s;
location ~ /jenkins/* {
proxy_pass http://jenkins;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
- jenkins context-path 맵핑
3. 설치 스텝
1. 도커 컴포즈 실행
docker compose up -d
2. 웹 브라우저 접속
http://도메인orIP/jenkins
- docker-compose.yml 파일 environment --prefix에 작성된 "jenkins" 를 통해접속 -> 별도 설정이 없다면 "http://localhost:8080" 으로 접속
3. 초기 관리자 비밀번호 확인
docker exec jenkins-container cat /var/jenkins_home/secrets/initialAdminPassword
- docker-compose.yml 파일에서 작성했던 컨테이너 이름으로 도커내부 연결
4. 플러그인 설치
- 기본 추천 설치
5. 관리자 계정 생성 후 대시보드 진입
4. Credentials 설정
젠킨스에서 다음 세 가지 credential을 미리 등록해둡니다.
ID | 종류 | 설명 |
github-access | SSH Key | private repo 접근용 |
dockerhub-access | Username/Password | Docker Hub 로그인용 |
ssh-key | SSH Key | 원격 서버 image pull용 |
- Jenkins 관리 > Credentials > (Global) > Add Credentials 에서 등록
4.1. Github Token 발급
- Github 로그인 후 > 우측상단 프로필 클릭 > Settings 클릭
- 좌측 네비게이션 최하단 "Developer settings" 클릭
- Personal access tokens > Tokens (classic) 클릭
- "Generate new token (classic)" 클릭
- 토큰 이름 및 만료기간 설정
- repo 필수 체크
- 토큰 생성 후 패스워드 별도 관리 필요
- Github → Repository → Settings → Webhooks
- Payload URL: http://<jenkins서버주소>/github-webhook/
- Content type: application/json
- 이벤트: Just the push event.
- Secret: (필요시 Jenkins와 동일하게 설정)
- Webhook 테스트를 위해 직접 커밋(push)하면 Jenkins가 자동으로 파이프라인을 실행합니다.
- jenkins > Add Credentials
- "Username with password", "Global" 선택
- ID 와 발급받은 Token 작성
4.2. DockerHub Token 발급
- Dockerhub 로그인 후 좌측 네비게이션바에서 "Personal access tokens" 클릭
- 설명과 만료날짜, 옵션을 작성한 후 "Generate"
- 토큰 별도 저장 필요
- jenkins > Add Credentials
- "Username with password", "Global" 선택
- ID 와 발급받은 Token 작성
4.3. SSH 키 생성
docker exec -it jenkins-container bash
mkdir -p /var/jenkins_home/.ssh
chmod 700 /var/jenkins_home/.ssh
ssh-keyscan -H 배포서버IP >> /var/jenkins_home/.ssh/known_hosts
chmod 644 /var/jenkins_home/.ssh/known_hosts
- Jenkins 컨테이너 내부에서 known_hosts 등록
ssh-keygen -t rsa -b 4096 -C "jenkins@ci" -f /var/jenkins_home/.ssh/id_rsa
- Jenkins 용 SSH Key 생성(컨테이너 내부)
cat /var/jenkins_home/.ssh/id_rsa.pub
- 위 내용 복사 후, 퍼블릭 키를 원격서버에 등록
- Jenkins 관리 → Credentials → (Global) 추가
- 종류: SSH Username with private key
- ID: 파이프라인에서 쓰는 이름
- Username: 원격 서버 계정
- Private Key: Enter directly → id_rsa 내용 복붙
cat /var/jenkins_home/.ssh/id_rsa
5. 파이프라인 스크립트 작성
- New Item > Pipeline 을 선택합니다.
- Triggers > GitHub hook trigger for GITScm polling 을 체크합니다.
- Pipeline script 를 선택하고 아래처럼 작성합니다.
pipeline {
agent any
options {
skipStagesAfterUnstable()
}
triggers {
githubPush()
}
environment {
IMAGE_NAME = "도커허브이미지 경로"
IMAGE_TAG = "도커허브 태그명"
FULL_TAG = "${IMAGE_NAME}:${IMAGE_TAG}"
}
stages {
stage('Clone') { // 소스 Clone
steps {
git credentialsId: 'github-access',
url: '깃허브URL',
branch: 'main'
}
}
stage('Build Jar') { // jar 빌드
steps {
sh 'chmod +x ./gradlew'
sh './gradlew bootJar'
}
}
stage('Docker Build') { // 도커빌드
steps {
sh "docker build -t ${FULL_TAG} ."
}
}
stage('Docker Push') { // 도커 푸시
steps {
withCredentials([
usernamePassword(
credentialsId: 'dockerhub-access',
usernameVariable: 'DOCKER_USER',
passwordVariable: 'DOCKER_PASS'
)
]) {
sh '''
echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin
docker push ${FULL_TAG}
'''
}
}
}
stage('Pull Image on Server') { // 이미지 pull 스크립트
steps {
sh '''
bash /scripts/pull_api.sh
'''
}
}
stage('Deploy Container') { // deploy 스크립트
steps {
sh '''
bash /scripts/deploy_api.sh
'''
}
}
}
}
- stage 는 프로젝트 상황에 맞게 수정하시면 됩니다.
- 단계별로 실행되는 모습을 확인할 수 있습니다.
감사합니다.
- Total
- Today
- Yesterday