Intro::
예시
pipeline {
agent any
parameters {
string(
name: 'IMAGE_TAG',
defaultValue: 'v2.0.0',
description: '배포할 태그 (예: v2.0.0)'
)
}
environment {
IMAGE_NAME = 'newshabit-4-nginx'
KEEP_COUNT = '2'
}
stages {
stage('Checkout') {
steps {
script {
try {
checkout([
$class: 'GitSCM',
branches: [[name: "refs/tags/${params.IMAGE_TAG}"]],
userRemoteConfigs: [[
url: "https://github.com/NewsHabit/newshabit_infra.git",
credentialsId: 'github-pat'
]]
])
echo "[ ${params.IMAGE_TAG} ]로 체크아웃 완료."
} catch (e) {
error "태그 ${params.IMAGE_TAG}가 존재하지 않습니다. 빌드 중단."
}
}
}
}
stage('Build & Deploy') {
steps {
dir('infra/nginx') {
withCredentials([
string(credentialsId: 'NEWSHABIT_4_ELASTIC_IP', variable: 'NEWSHABIT_4_ELASTIC_IP'),
string(credentialsId: 'INFRA_ALLOWED_IP', variable: 'INFRA_ALLOWED_IP')
]) {
sh '''
echo "1. Docker 이미지 빌드 및 컨테이너 실행"
docker-compose -f newshabit-4/docker-compose.nginx.newshabit-4.yml build
docker-compose -f newshabit-4/docker-compose.nginx.newshabit-4.yml down
docker-compose -f newshabit-4/docker-compose.nginx.newshabit-4.yml up -d
'''
}
}
}
}
stage('Clean Old Tags') {
steps {
sh '''
echo "2. 오래된 태그 자동 삭제 (최신 $KEEP_COUNT 개 제외)"
offset=$(( KEEP_COUNT + 1 ))
tags=$(docker images $IMAGE_NAME --format '{{.Tag}}' | tail -n +$offset)
if [ -z "$tags" ]; then
echo "삭제할 태그가 없습니다."
else
echo "삭제 대상 태그:"
printf '%s\n' "$tags"
for tag in $tags; do
docker rmi $IMAGE_NAME:$tag || echo "[경고] $IMAGE_NAME:$tag 삭제 실패"
done
fi
'''
}
}
}
post {
always {
cleanWs()
echo "Pipeline complete."
}
}
}
Bash
복사
ssh 로 접속해서 배포
pipeline {
agent { label 'docker-agent' }
parameters {
string(
name: 'IMAGE_TAG',
defaultValue: 'v2.0.0',
description: '배포할 태그 (예: v2.0.0)'
)
}
environment {
IMAGE_NAME = 'newshabit-1-nginx'
KEEP_COUNT = '2'
EC2_USER = 'ec2-user'
REMOTE_DIR = '/home/ec2-user/app/nginx'
}
stages {
stage('Checkout') {
steps {
script {
try {
checkout([
$class: 'GitSCM',
branches: [[name: "refs/tags/${params.IMAGE_TAG}"]],
userRemoteConfigs: [[
url: 'https://github.com/NewsHabit/newshabit_infra.git',
credentialsId: 'github-pat'
]]
])
echo "✔ 태그 ${params.IMAGE_TAG} 체크아웃 완료"
} catch (e) {
error "❌ 태그 ${params.IMAGE_TAG}가 존재하지 않습니다. 빌드 중단"
}
}
}
}
stage('Deploy to EC2') {
steps {
withCredentials([
file(credentialsId: 'NEWSHABIT_1_PEM', variable: 'NEWSHABIT_1_PEM'),
string(credentialsId: 'NEWSHABIT_1_DOMAIN', variable: 'NEWSHABIT_1_DOMAIN'),
string(credentialsId: 'NEWSHABIT_1_PRIVATE_IP', variable: 'NEWSHABIT_1_PRIVATE_IP'),
string(credentialsId: 'NEWSHABIT_2_PRIVATE_IP', variable: 'NEWSHABIT_2_PRIVATE_IP'),
string(credentialsId: 'NEWSHABIT_3_PRIVATE_IP', variable: 'NEWSHABIT_3_PRIVATE_IP')
]) {
sh """
echo '▶ 소스 및 Compose 파일 복사'
scp -o StrictHostKeyChecking=no -i ${NEWSHABIT_1_PEM} -r infra/nginx/* \\
${EC2_USER}@${NEWSHABIT_1_PRIVATE_IP}:${REMOTE_DIR}/
echo '▶ EC2 빌드·배포 시작'
ssh -o StrictHostKeyChecking=no -i ${NEWSHABIT_1_PEM} ${EC2_USER}@${NEWSHABIT_1_PRIVATE_IP} << EOF
set -e
export IMAGE_TAG=${params.IMAGE_TAG}
export IMAGE_NAME=${IMAGE_NAME}
export KEEP_COUNT=${KEEP_COUNT}
export NEWSHABIT_1_DOMAIN=${NEWSHABIT_1_DOMAIN}
export NEWSHABIT_2_PRIVATE_IP=${NEWSHABIT_2_PRIVATE_IP}
export NEWSHABIT_3_PRIVATE_IP=${NEWSHABIT_3_PRIVATE_IP}
cd ${REMOTE_DIR}
echo "• Docker Compose 이미지 빌드"
docker-compose -f newshabit-1/docker-compose.nginx.newshabit-1.yml build --no-cache --pull
echo "• 컨테이너 갱신"
docker-compose -f newshabit-1/docker-compose.nginx.newshabit-1.yml down
docker-compose -f newshabit-1/docker-compose.nginx.newshabit-1.yml up -d
echo "• 오래된 이미지 정리 (최신 \${KEEP_COUNT}개 제외)"
docker images \${IMAGE_NAME} --format '{{.Tag}}' \\
| sort -rV \\
| tail -n +\$((KEEP_COUNT+1)) \\
| xargs -r -n1 docker rmi || true
echo "• 배포 파일 정리"
rm -rf ${REMOTE_DIR}/*
EOF
"""
}
}
}
}
post {
always {
cleanWs()
echo "✅ 파이프라인 완료"
}
}
}
JavaScript
복사
부모 pipeline
pipeline {
agent any
parameters {
choice(name: 'SERVICE', choices: ['deploy', 'rollback'], description: '실행할 작업을 선택하세요')
string(name: 'IMAGE_TAG', defaultValue: 'v1.0.0', description: '배포 이미지의 태그를 입력하세요')
}
stages {
stage('선택한 작업 실행') {
steps {
script {
if (params.SERVICE == 'deploy') {
echo "배포 작업을 시작합니다."
build job: 'Service-A-Pipeline',
parameters: [
string(name: 'IMAGE_TAG', value: params.IMAGE_TAG)
],
wait: true,
propagate: true
} else if (params.SERVICE == 'rollback') {
echo "롤백 작업을 시작합니다."
build job: 'Service-B-Pipeline',
parameters: [
string(name: 'IMAGE_TAG', value: params.IMAGE_TAG)
],
wait: true,
propagate: true
} else {
echo "유효하지 않은 작업 선택"
}
}
}
}
}
post {
always {
cleanWs()
echo "선택된 작업이 완료되었습니다."
}
}
}
Groovy
복사
자식 pipeline
pipeline {
agent any
// 사용자로부터 배포 환경을 입력받기 위한 파라미터 설정
parameters {
string(
name: 'IMAGE_TAG',
defaultValue: 'v1.0.0',
description: '배포할 환경 이름을 입력하세요 (예: production, staging)'
)
}
stages {
stage('환경 변수 출력') {
steps {
// 파라미터로 입력받은 값(배포 환경)을 콘솔에 출력
echo "배포: ${params.IMAGE_TAG}"
}
}
}
post {
always {
echo "자식 파이프라인 실행 완료"
}
}
}
Groovy
복사
깃 연결
pipeline {
agent any
stages {
stage('Checkout 특정 브랜치') {
steps {
// Git 저장소에서 특정 브랜치를 체크아웃함.
checkout([
$class: 'GitSCM',
branches: [[name: '*/feature-branch']], // 또는 'origin/feature-branch'
userRemoteConfigs: [[url: 'https://github.com/username/repository.git']]
])
echo "특정 브랜치(feature-branch)로 체크아웃 완료."
}
}
}
}
Groovy
복사
pipeline {
agent any
stages {
stage('Checkout 특정 태그') {
steps {
// Git 저장소에서 특정 태그(v1.0.0)를 체크아웃함.
checkout([
$class: 'GitSCM',
branches: [[name: 'refs/tags/v1.0.0']],
userRemoteConfigs: [[url: 'https://github.com/username/repository.git']]
])
echo "특정 태그(v1.0.0)로 체크아웃 완료."
}
}
}
}
Groovy
복사
자체서버 배포할떄