젠킨스를 사용해 보겠습니다.
Jenkins Item 생성 : item name(first) - docker 명령 실행 확인
Build Steps : Execute shell ⇒ Save 후 지금 빌드 : Console Output 확인
echo "docker check" | tee test.txt
docker ps
Gogs Repo 자격증명 설정(gogs-dev-app) : Jenkins 관리 → Credentials → Globals → Add Credentials
Jenkins Item 생성 : item name(second) - 소스코드관리(Git) 설정 + 빌드 파라미터
+아래 사진처럼 설정
Build Steps : Execute shell
echo "{$FirstPara}"
cat VERSION
확인(버전 정보 출력)
파이프라인
파이프라인 Pipeline : CD 파이프라인을 구현하고 통합할 때 사용하는 플러그인 스크립트 모음 - Docs
위 과정을 자동화 하자!! -> 전체과정을 코드로 만들어서 진행!
파이프라인 2가지 구문 : 선언형 파이프라인(권장)과 스크립트형 파이프라인
Jenkins Plugin 설치
- Pipeline Stage View - Docs
- Docker Pipeline : building, testing, and using Docker images from Jenkins Pipeline - Docs
- Gogs : Webhook Plugin - Docs
Jenkins 도커 계정/암호 자격 증명 설정 : Add Credentials(Global) - Kind(Username with password)
- Username : <도커 계정명>
- Password : <도커 계정 암호
혹은 토큰> - ID : dockerhub-credentials ⇒ 자격증명 이름으로, pipeline 사용 예정
Jenkins Item 생성(Pipeline) : item name(pipeline-ci)
Pipeline script
pipeline {
agent any
environment {
DOCKER_IMAGE = '<자신의 도커 허브 계정>/dev-app' // Docker 이미지 이름
}
stages {
stage('Checkout') {
steps {
git branch: 'main',
url: 'http://192.168.254.124:3000/devops/dev-app.git', // Git에서 코드 체크아웃
credentialsId: 'gogs-dev-app' // Credentials ID
}
}
stage('Read VERSION') {
steps {
script {
// VERSION 파일 읽기
def version = readFile('VERSION').trim()
echo "Version found: ${version}"
// 환경 변수 설정
env.DOCKER_TAG = version
}
}
}
stage('Docker Build and Push') {
steps {
script {
docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
// DOCKER_TAG 사용
def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
appImage.push()
}
}
}
}
}
post {
success {
echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
}
failure {
echo "Pipeline failed. Please check the logs."
}
}
}
성공!
도커허브도 확인
도커 기반 애플리케이션 CI/CD 구성
Gogs Webhooks 설정 : Jenkins Job Trigger
gogs 에 app.ini 파일 수정 후 컨테이너 재기동 - issue
[security]
INSTALL_LOCK = true
SECRET_KEY = j2xaUPQcbAEwpIu
LOCAL_NETWORK_ALLOWLIST = 192.168.254.124 # 각자 자신의 PC IP
Payload URL : http://192.168.254.124:8080/gogs-webhook/?job=**SCM-Pipeline**/
Content Type : application/json
Secret : qwe123
When should this webhook be triggered? : Just the push event
Active : Check
설정완료
Jenkins Item 생성(Pipeline) : item name(SCM-Pipeline)
- GitHub project : http://***<mac IP>***:3000/***<Gogs 계정명>***/dev-app ← .git 은 제거
- Use Gogs secret : qwe123
- Build Triggers : Build when a change is pushed to Gogs 체크
- Pipeline script from SCM
- SCM : Git
- Repo URL(http://***<mac IP>***:3000/***<Gogs 계정명>***/dev-app)
- Credentials(devops/***)
- Branch(*/main)
- Script Path : Jenkinsfile
- SCM : Git
Jenkinsfile 작성 후 Git push
jenkins 컨테이너(혹은 로컬에서 git 작업)에서 아래 작업
# Jenkinsfile 빈 파일 작성
docker compose exec jenkins touch /var/jenkins_home/dev-app/Jenkinsfile
# 버전 0.0.2 수정 : 아래 입력 잘 안될 경우 VSCODE(Docker플러그인)에서 직접 수정
docker compose exec jenkins sh -c 'echo "0.0.2" > /var/jenkins_home/dev-app/VERSION'
VSCODE 로 jenkins 컨테이너 내부 파일 Open 후 작성
pipeline {
agent any
environment {
DOCKER_IMAGE = '<자신의 도커 허브 계정>/dev-app' // Docker 이미지 이름
}
stages {
stage('Checkout') {
steps {
git branch: 'main',
url: 'http://192.168.254.124:3000/devops/dev-app.git', // Git에서 코드 체크아웃
credentialsId: 'gogs-dev-app' // Credentials ID
}
}
stage('Read VERSION') {
steps {
script {
// VERSION 파일 읽기
def version = readFile('VERSION').trim()
echo "Version found: ${version}"
// 환경 변수 설정
env.DOCKER_TAG = version
}
}
}
stage('Docker Build and Push') {
steps {
script {
docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
// DOCKER_TAG 사용
def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
appImage.push()
}
}
}
}
}
post {
success {
echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
}
failure {
echo "Pipeline failed. Please check the logs."
}
}
}
작성된 파일 push : jenkins 컨테이너 bash 내부 진입해서 작업 진행 ← 호스트에서 직접 작업하셔도 됩니다.
#
docker compose exec jenkins bash
---------------------------------
cd /var/jenkins_home/dev-app/
git add . && git commit -m "Jenkinsfile add & VERSION 0.0.2 Changed" && git push -u origin main
돌아간다!
한 번 실패 후 다시..!
확인
Final : 도커 빌드 후 기존 컨테이너 중지/제거 후 신규 컨테이너 실행 Jenkinsfile pipeline 수정 후 빌드 (SCM-Pipeline)
Jenkinsfile 수정 후 git push → tcp (기본값:4000) 는 파라미터로 입력 받게 설정하게 해볼것
pipeline {
agent any
environment {
DOCKER_IMAGE = '<자신의 도커 허브 계정>/dev-app' // Docker 이미지 이름
CONTAINER_NAME = 'dev-app' // 컨테이너 이름
}
stages {
stage('Checkout') {
steps {
git branch: 'main',
url: 'http://192.168.254.124:3000/devops/dev-app.git', // Git에서 코드 체크아웃
credentialsId: 'gogs-dev-app' // Credentials ID
}
}
stage('Read VERSION') {
steps {
script {
// VERSION 파일 읽기
def version = readFile('VERSION').trim()
echo "Version found: ${version}"
// 환경 변수 설정
env.DOCKER_TAG = version
}
}
}
stage('Docker Build and Push') {
steps {
script {
docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
// DOCKER_TAG 사용
def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
appImage.push()
appImage.push("latest") // 빌드 이미지 push 할 때, 2개의 버전(현재 버전, latest 버전)을 업로드
}
}
}
}
stage('Check, Stop and Run Docker Container') {
steps {
script {
// 실행 중인 컨테이너 확인
def isRunning = sh(
script: "docker ps -q -f name=${CONTAINER_NAME}",
returnStdout: true
).trim()
if (isRunning) {
echo "Container '${CONTAINER_NAME}' is already running. Stopping it..."
// 실행 중인 컨테이너 중지
sh "docker stop ${CONTAINER_NAME}"
// 컨테이너 제거
sh "docker rm ${CONTAINER_NAME}"
echo "Container '${CONTAINER_NAME}' stopped and removed."
} else {
echo "Container '${CONTAINER_NAME}' is not running."
}
// 5초 대기
echo "Waiting for 5 seconds before starting the new container..."
sleep(5)
// 신규 컨테이너 실행
echo "Starting a new container '${CONTAINER_NAME}'..."
sh """
docker run -d --name ${CONTAINER_NAME} -p 4000:80 ${DOCKER_IMAGE}:${DOCKER_TAG}
"""
}
}
}
}
post {
success {
echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
}
failure {
echo "Pipeline failed. Please check the logs."
}
}
}
컨테이너 확인
docker image
docker ps
curl http://127.0.0.1:4000
server.py 수정 후 VERSION 수정 후 push 후 생성된 컨테이너 접속 후 반영 확인
# server.py 수정
response_string = now.strftime("The time is %-I:%M:%S %p, Study 1week End.\n")
# VERSION 수정
# Jenkins 컨테이너 내부에서 git push
jenkins@5c1ba7016f9e:~/dev-app$ git add . && git commit -m "VERSION $(cat VERSION) Changed" && git push -u origin main
# 호스트 PC에서 반복 접속 실행 : 서비스 중단 시간 체크!
while true; do curl -s --connect-timeout 1 http://127.0.0.1:4000 ; date; sleep 1 ; done
확인
'study > CICD' 카테고리의 다른 글
CICD 스터디 3주차 두번째 (0) | 2024.12.22 |
---|---|
CICD 스터디 3주차 첫번째 (0) | 2024.12.22 |
CICD 스터디 2주차 (1) | 2024.12.15 |
CICD 스터디 1주차 첫번째 (1) | 2024.12.06 |