Jenkinsfile 작성하기

김재혁·2025년 2월 12일

공통 프로젝트

목록 보기
7/12

Jenkinsfile 작성

0. 전체 코드

pipeline {
    agent any

    environment {
        FRONTEND_IMAGE = "rublin322/moonggeul-frontend:latest"
        BACKEND_IMAGE  = "rublin322/moonggeul-backend:latest"
        DEPLOY_HOST = "ubuntu@i12b206.p.ssafy.io"
        DEPLOY_PATH = "/home/ubuntu/moonggeul"
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
                script {
                    echo "현재 브랜치: ${env.BRANCH_NAME}"
                    echo "현재 워크스페이스: ${env.WORKSPACE}"
                    // def deployBranches = ['main', 'dev']
                    // if (!deployBranches.contains(env.BRANCH_NAME)) {
                    //     error "현재 브랜치(${env.BRANCH_NAME})에서는 배포를 수행하지 않습니다."
                    // }
                }
            }
        }
        stage('Prepare Environment') {
            steps {
                withCredentials([file(credentialsId: 'env-file-content', variable: 'ENV_FILE_PATH')]) {
                    script {
                        def envContent = readFile(ENV_FILE_PATH)
                        writeFile file: '.env', text: envContent
                    }
                }
            }
        }
        stage('Build Frontend Docker Image') {
            steps {
                dir('frontend') {
                    sh "docker build -t ${FRONTEND_IMAGE} ."
                }
            }
        }
        stage('Build Backend Docker Image') {
            steps {
                dir('backend') {
                    sh "docker build -t ${BACKEND_IMAGE} ."
                }
            }
        }
        stage('Push Docker Images') {
            steps {
                withDockerRegistry([credentialsId: 'dockerhub-token', url: '']) {
                    sh "docker push ${FRONTEND_IMAGE}"
                    sh "docker push ${BACKEND_IMAGE}"
                }
            }
        }
        stage('Deploy to EC2') {
            steps {
                sshagent(credentials: ['ec2-ssh-key']) {
                    sh "scp -o StrictHostKeyChecking=no .env ${DEPLOY_HOST}:${DEPLOY_PATH}/.env"
                    sh "scp -o StrictHostKeyChecking=no docker-compose.yml ${DEPLOY_HOST}:${DEPLOY_PATH}/docker-compose.yml"
                    sh """
                    ssh -o StrictHostKeyChecking=no ${DEPLOY_HOST} '
                        cd ${DEPLOY_PATH} &&
                        docker compose down --remove-orphans &&
                        docker compose pull &&
                        docker compose up -d &&
                        docker image prune -f &&
                        rm -f ${DEPLOY_PATH}/.env
                    '
                    """
                }
            }
        }
    }
    
    post {
        always {
            echo '배포 파이프라인 종료'
        }
    }
}

1. 개요

이 Jenkinsfile은 CI/CD 파이프라인을 자동화하여 프론트엔드 및 백엔드 Docker 이미지를 빌드하고, 이를 Docker Hub에 푸시한 뒤, 최종적으로 EC2 서버에 배포하는 과정을 포함합니다.


2. Jenkinsfile 단계별 설명

(1) 파이프라인 기본 설정

pipeline {
    agent any
  • agent any: Jenkins에서 사용 가능한 모든 에이전트(노드)에서 실행될 수 있도록 지정합니다.

(2) 환경 변수 설정

    environment {
        FRONTEND_IMAGE = "rublin322/moonggeul-frontend:latest"
        BACKEND_IMAGE  = "rublin322/moonggeul-backend:latest"
        DEPLOY_HOST = "ubuntu@i12b206.p.ssafy.io"
        DEPLOY_PATH = "/home/ubuntu/moonggeul"
    }
  • FRONTEND_IMAGE / BACKEND_IMAGE: Docker Hub에 푸시할 이미지 이름 및 태그 설정
  • DEPLOY_HOST: 배포할 EC2 서버의 SSH 주소
  • DEPLOY_PATH: EC2 서버에서 애플리케이션이 배포될 경로 지정

(3) Checkout 단계 - 코드 체크아웃

        stage('Checkout') {
            steps {
                checkout scm
                script {
                    echo "현재 브랜치: ${env.BRANCH_NAME}"
                    echo "현재 워크스페이스: ${env.WORKSPACE}"
                }
            }
        }
  • SCM 체크아웃: 현재 저장소에서 코드 가져오기
  • 환경 변수 출력: 현재 브랜치 및 워크스페이스 정보를 출력

(4) Prepare Environment 단계 - 환경 변수 설정

        stage('Prepare Environment') {
            steps {
                withCredentials([file(credentialsId: 'env-file-content', variable: 'ENV_FILE_PATH')]) {
                    script {
                        def envContent = readFile(ENV_FILE_PATH)
                        writeFile file: '.env', text: envContent
                    }
                }
            }
        }
  • 환경 파일 적용: .env 파일을 Jenkins에서 가져와 저장
  • 보안 적용: withCredentials를 사용해 민감한 환경 변수를 안전하게 가져옴

(5) Build Frontend Docker Image 단계 - 프론트엔드 이미지 빌드

        stage('Build Frontend Docker Image') {
            steps {
                dir('frontend') {
                    sh "docker build -t ${FRONTEND_IMAGE} ."
                }
            }
        }
  • dir('frontend'): 프론트엔드 디렉토리로 이동하여 Docker 이미지 빌드

(6) Build Backend Docker Image 단계 - 백엔드 이미지 빌드

        stage('Build Backend Docker Image') {
            steps {
                dir('backend') {
                    sh "docker build -t ${BACKEND_IMAGE} ."
                }
            }
        }
  • dir('backend'): 백엔드 디렉토리로 이동하여 Docker 이미지 빌드

(7) Push Docker Images 단계 - Docker Hub에 이미지 푸시

        stage('Push Docker Images') {
            steps {
                withDockerRegistry([credentialsId: 'dockerhub-token', url: '']) {
                    sh "docker push ${FRONTEND_IMAGE}"
                    sh "docker push ${BACKEND_IMAGE}"
                }
            }
        }
  • Docker Hub 로그인: dockerhub-token 자격 증명을 사용하여 인증
  • 이미지 푸시: 프론트엔드 및 백엔드 이미지를 Docker Hub에 업로드

(8) Deploy to EC2 단계 - EC2 서버에 배포

        stage('Deploy to EC2') {
            steps {
                sshagent(credentials: ['ec2-ssh-key']) {
                    sh "scp -o StrictHostKeyChecking=no .env ${DEPLOY_HOST}:${DEPLOY_PATH}/.env"
                    sh "scp -o StrictHostKeyChecking=no docker-compose.yml ${DEPLOY_HOST}:${DEPLOY_PATH}/docker-compose.yml"
                    sh """
                    ssh -o StrictHostKeyChecking=no ${DEPLOY_HOST} '
                        cd ${DEPLOY_PATH} &&
                        docker compose down --remove-orphans &&
                        docker compose pull &&
                        docker compose up -d &&
                        docker image prune -f &&
                        rm -f ${DEPLOY_PATH}/.env
                    '
                    """
                }
            }
        }
  • SSH 에이전트 사용: sshagent를 이용해 EC2에 SSH 접속
  • 파일 전송:
    • .env 파일과 docker-compose.yml을 EC2로 전송
  • 배포 스크립트 실행:
    • 기존 컨테이너 중단 및 불필요한 컨테이너 제거 (docker compose down --remove-orphans)
    • 최신 이미지 다운로드 (docker compose pull)
    • 새로운 컨테이너 실행 (docker compose up -d)
    • 사용하지 않는 Docker 이미지 정리 (docker image prune -f)
    • 배포 완료 후 .env 파일 삭제 (rm -f ${DEPLOY_PATH}/.env)

(9) Post 단계 - 배포 완료 메시지 출력

    post {
        always {
            echo '배포 파이프라인 종료'
        }
    }
  • 파이프라인 종료 메시지 출력: 모든 과정이 완료되면 종료 메시지를 출력
profile
志鐵心鏡

0개의 댓글