들어가며
배포서버를 Jenkins 기반 CI/CD 전용 서버로 활용하기 위한 1차 검증 내용을 정리했습니다.
목표는 정적 웹 샘플 프로젝트를 기준으로, 아래의 End-to-End 흐름이 실제로 한 번 끝까지 정상 동작하는지 확인하는 것입니다.
- 브랜치 작업 → Git push
- Jenkins Pipeline 실행
- Docker 이미지 빌드
- 이미지 tar 산출물 생성
- 개발서버 전송
- 개발서버에서 이미지 로드 및 컨테이너 기동
- 개발서버 내부에서 curl로 응답 확인
검증 범위
포함
- Jenkins 설치 및 기동 확인
- Jenkins 실행 Java 21 적용
- Git 설치 및 저장소 연동
- 개발서버 배포 계정 생성 및 SSH 키 기반 접속 구성
- Pipeline 기반 checkout
- Docker 이미지 빌드
- 이미지 tar 생성
- 개발서버 전송(SCP)
- 개발서버에서 docker load 및 테스트 컨테이너 기동
- 개발서버 내부 curl 검증
제외
- 운영서버 배포
- Git webhook 또는 polling 자동 트리거
- Spring Boot 및 Maven 빌드
- 무중단 배포
- 스테이징 환경
- 사설 Docker Registry
검증 환경
배포서버( Jenkins 서버 )
역할: CI/CD 실행 및 빌드 서버
- Jenkins, Java 21, Git, Docker 설치
- Pipeline 실행
- Docker 이미지 빌드 및 산출물 생성
- 개발서버로 산출물 전송
개발서버
역할: 1차 배포 및 검증 대상 서버
- 배포용 계정 devops 생성
- 공개키 등록
- Docker 설치 및 기동
- 테스트 컨테이너 별도 실행
사전 준비(체크리스트)
- Jenkins 설치 및 기동 완료
- Jenkins 접속 포트 9090 적용
- Java 21 적용 완료
- Git 설치 완료
- Docker 설치 완료
- Jenkins Credentials에 개발서버 SSH 키 등록 완료
- Kind: SSH Username with private key
- Username: devops
- Credential ID: ssh-devops-devserver
- 배포서버에서 devops@개발서버 SSH 접속 확인 완료
Git 저장소 및 샘플 구조
브랜치
- feature/static-cicd-test
디렉터리 구조(예시)
project-root/
├─ Jenkinsfile
├─ (기존 Java 프로젝트 파일)
└─ cicd-static-sample/
├─ index.html
└─ Dockerfile
샘플 파일
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello Jenkins</title>
</head>
<body>
<h1>Hello Jenkins CI/CD</h1>
<p>Static Web Deploy Success</p>
</body>
</html>
Dockerfile
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
전체 흐름(중요 개념)
이번 1차 검증에서 핵심은 작업 위치가 서로 다르다는 점입니다.
- 원격 Git 저장소: 소스 원본
- 배포서버 Jenkins Workspace: checkout 된 소스가 존재하는 작업 공간
- 배포서버 Docker 엔진: 이미지 빌드 수행 위치
- 개발서버: 컨테이너 실행 및 검증 위치
즉 Pipeline은 저장소에서 파일을 직접 조작하는 것이 아니라,
소스를 Jenkins Workspace로 가져온 뒤(Checkout) 배포서버에서 빌드하고, 산출물을 개발서버로 전달하는 구조입니다.
Jenkins Workspace 확인 팁
- Jenkins 서버 쉘
ls -al /var/lib/jenkins/workspace
ls -al /var/lib/jenkins/workspace/작업명
- Pipeline에서 확인
sh 'pwd'
dir('cicd-static-sample') 의미
아래 구문은 셸의 cd cicd-static-sample과 같습니다.
dir('cicd-static-sample') {
sh 'docker build -t sample-static-web:static-cicd-test .'
}
정적 웹 샘플과 Dockerfile이 프로젝트 루트가 아니라 하위 폴더에 있으므로, docker build의 기준 경로를 맞추기 위해 필요합니다.
산출물(Artifact) 관리 정책
저장 경로
/data/jenkins-artifacts/static-web
파일 예시
/data/jenkins-artifacts/static-web/sample-static-web-static-cicd-test.tar
운영 방식
- 최신 테스트 산출물 1개 기준으로 덮어쓰기
- 이미지 이름과 태그는 충돌 방지를 위해 테스트용으로 분리
Jenkins Pipeline 스크립트(예시)
Stage 구성:
- Checkout
- Check Files
- Build Image
- Save Image
- Transfer Image
- Deploy To Dev
- Verify On Dev
아래 스크립트의 원격저장소URL, 개발서버IP는 실제 값으로 교체하세요.
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: 'feature/static-cicd-test',
credentialsId: 'git-sample-creds',
url: '원격저장소URL'
}
}
stage('Check Files') {
steps {
sh 'pwd'
sh 'ls -al'
sh 'ls -al cicd-static-sample'
sh 'cat cicd-static-sample/index.html'
}
}
stage('Build Image') {
steps {
dir('cicd-static-sample') {
sh 'docker build -t sample-static-web:static-cicd-test .'
}
}
}
stage('Save Image') {
steps {
sh '''
rm -f /data/jenkins-artifacts/static-web/sample-static-web-static-cicd-test.tar
docker save -o /data/jenkins-artifacts/static-web/sample-static-web-static-cicd-test.tar sample-static-web:static-cicd-test
ls -lh /data/jenkins-artifacts/static-web/
'''
}
}
stage('Transfer Image') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: 'ssh-devops-devserver',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh '''
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY" ${SSH_USER}@개발서버IP 'mkdir -p /home/devops/deploy'
scp -o StrictHostKeyChecking=no -i "$SSH_KEY" \\
/data/jenkins-artifacts/static-web/sample-static-web-static-cicd-test.tar \\
${SSH_USER}@개발서버IP:/home/devops/deploy/
'''
}
}
}
stage('Deploy To Dev') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: 'ssh-devops-devserver',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh '''
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY" ${SSH_USER}@개발서버IP '
docker load -i /home/devops/deploy/sample-static-web-static-cicd-test.tar &&
docker rm -f sample-static-web-test || true &&
docker run -d --name sample-static-web-test -p 8082:80 sample-static-web:static-cicd-test &&
docker ps | grep sample-static-web-test
'
'''
}
}
}
stage('Verify On Dev') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: 'ssh-devops-devserver',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh '''
ssh -o StrictHostKeyChecking=no -i "$SSH_KEY" ${SSH_USER}@개발서버IP '
curl -o /dev/null -s -w "%{http_code}\\n" <http://127.0.0.1:8082>
'
'''
}
}
}
}
}
개발서버에서 수동 검증 명령(필요 시)
# 컨테이너 확인
docker ps
# 응답 확인
curl -s <http://127.0.0.1:8082>
# HTTP 상태코드만 확인
curl -o /dev/null -s -w "%{http_code}\\n" <http://127.0.0.1:8082>
# 이미지 확인
docker images
테스트 컨테이너 운영 정책
기존 개발 컨테이너와 충돌을 피하기 위해 테스트용으로 분리했습니다.
- 이미지: sample-static-web:static-cicd-test
- 컨테이너: sample-static-web-test
- 포트: 8082:80
검증 결과
확인된 사항
- Jenkins 기동 정상
- Java 21 적용 정상
- Git checkout 정상
- Docker 이미지 빌드 정상
- tar 산출물 생성 정상
- 배포서버 → 개발서버 전송 정상
- 개발서버에서 이미지 로드 및 컨테이너 기동 정상
- 개발서버 내부 curl 검증에서 HTTP 200 확인
결론
정적 웹 샘플 기준으로 Jenkins 기반 CI/CD 1차 검증은 정상 완료되었습니다.
다음 단계(2차 목표)
다음 단계에서는 Spring Boot + Maven + Docker로 확장하여 검증할 예정입니다.
- Spring Boot 샘플 구성
- Maven compile 및 package
- Docker 이미지 생성 및 배포
- Git webhook 또는 polling 기반 자동 트리거 검토
'시스템 관리 > CI_CD' 카테고리의 다른 글
| 젠킨스 환경 구축 가이드 (0) | 2026.03.12 |
|---|