๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ Jenkins์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ Jenkins์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

Habrรฉ์—๋Š” Jenkins์— ๋Œ€ํ•œ ๊ธฐ์‚ฌ๊ฐ€ ๋งŽ์ด ์žˆ์ง€๋งŒ Jenkins์™€ Docker ์—์ด์ „ํŠธ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•œ ์˜ˆ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ธฐ์‚ฌ๋Š” ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ๋“  ์ธ๊ธฐ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ๋„๊ตฌ ๋“œ๋ก .io, ๋น„ํŠธ๋ฒ„ํ‚ท ํŒŒ์ดํ”„๋ผ์ธ, GitLab, GitHub ์ž‘์—… ๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ๋ชจ๋“  ๊ฒƒ์„ ์šฉ๊ธฐ์— ๋‹ด์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์  ํ‚จ์Šค๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์˜ค๋Š˜๋‚  ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค. Jenkins 2๋Š” ์ž‘์—…์— ํƒ์›”ํ•ฉ๋‹ˆ๋‹ค. ๋„์ปค ์—์ด์ „ํŠธ. ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๋‚ด ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๊ณ  ์Šค์Šค๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์™œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๋Š” ํšŒ์‚ฌ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹œํŠธ๋กœ๋Š„ ์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— Node.JS, Gradle, Ruby, JDK ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ฒ„์ „์„ ์–ด์…ˆ๋ธ”๋ฆฌ ์‹œ์Šคํ…œ์— ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฒ„์ „ ์ถฉ๋Œ์„ ํ”ผํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ, nvm, rvm๊ณผ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ์ž๊ฐ€ ์žˆ๋‹ค๊ณ  ๋งํ•˜๋ฉด ์˜ณ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๊ฒƒ์ด ๊ทธ๋ ‡๊ฒŒ ์ˆœ์กฐ๋กญ๊ฒŒ ์ง„ํ–‰๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ ์ด๋Ÿฌํ•œ ์†”๋ฃจ์…˜์—๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ •๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฐ ๋งŽ์€ ์–‘์˜ ๋Ÿฐํƒ€์ž„;
  • ๋™์ผํ•œ ๋Ÿฐํƒ€์ž„์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒ„์ „ ๊ฐ„์— ์ถฉ๋Œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ชจ๋“  ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ ์„ธํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ฌธ์ œ๋„ ์žˆ๋Š”๋ฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๋„์ปค์˜ ์  ํ‚จ์Šค

Docker๋Š” ์ด์ œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์ž˜ ์ž๋ฆฌ์žก์•˜๊ธฐ ๋•Œ๋ฌธ์— Docker๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์†”๋ฃจ์…˜์€ Docker์— Jenkins๋ฅผ ๋‘๊ณ  ๋‹ค๋ฅธ Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์งˆ๋ฌธ์€ 2013๋…„์— โ€œ์ด์ œ Docker ๋‚ด์—์„œ Docker๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.".

์ฆ‰, ์ž‘์—… ์ปจํ…Œ์ด๋„ˆ์— Docker ์ž์ฒด๋ฅผ ์„ค์น˜ํ•˜๊ณ  ํŒŒ์ผ์„ ๋งˆ์šดํŠธํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. /var/run/docker.sock.

๋‹ค์Œ์€ Jenkins์šฉ์œผ๋กœ ๋‚˜์˜จ Dockerfile์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

FROM jenkins/jenkins:lts

USER root

RUN apt-get update && 

apt-get -y install apt-transport-https 
     ca-certificates 
     curl 
     gnupg2 
     git 
     software-properties-common && 
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && 
add-apt-repository 
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") 
   $(lsb_release -cs) 
   stable" && 
apt-get update && 
apt-get -y install docker-ce && 
usermod -aG docker jenkins

RUN curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose 

RUN apt-get clean autoclean && apt-get autoremove โ€”yes && rm -rf /var/lib/{apt,dpkg,cache,log}/

USER jenkins

๋”ฐ๋ผ์„œ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์—์„œ Docker ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” Docker ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.

๋นŒ๋“œ ์„ค์ •

์–ผ๋งˆ ์ „ Jenkins๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ทœ์น™์„ ์„ค๋ช…ํ•  ๊ธฐํšŒ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋กœ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์ €์žฅ์†Œ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๋นŒ๋“œ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํฌํ•จ๋œ ํŠน์ˆ˜ Dockerfile์„ ์ €์žฅ์†Œ ์ž์ฒด์— ๋„ฃ์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ๋ฐœ์ž ์ž์‹ ์ด ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ์„ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ˜ธ์ŠคํŠธ์— ํŠน์ • ๋ฒ„์ „์˜ Node.JS๋ฅผ ์„ค์น˜ํ•˜๋„๋ก OPS์— ์š”์ฒญํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

FROM node:12.10.0-alpine

RUN npm install yarn -g

์ด ๋นŒ๋“œ ์ด๋ฏธ์ง€๋Š” ๋Œ€๋ถ€๋ถ„์˜ Node.JS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Sonar ์Šค์บ๋„ˆ๊ฐ€ ํฌํ•จ๋œ JVM ํ”„๋กœ์ ํŠธ์šฉ ์ด๋ฏธ์ง€๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ์กฐ๋ฆฝ์— ํ•„์š”ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FROM adoptopenjdk/openjdk12:latest

RUN apt update 
    && apt install -y 
        bash unzip wget

RUN mkdir -p /usr/local/sonarscanner 
    && cd /usr/local/sonarscanner 
    && wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-linux.zip 
    && unzip sonar-scanner-cli-3.3.0.1492-linux.zip 
    && mv sonar-scanner-3.3.0.1492-linux/* ./ 
    && rm sonar-scanner-cli-3.3.0.1492-linux.zip 
    && rm -rf sonar-scanner-3.3.0.1492-linux 
    && ln -s /usr/local/sonarscanner/bin/sonar-scanner /usr/local/bin/sonar-scanner

ENV PATH $PATH:/usr/local/sonarscanner/bin/
ENV SONAR_RUNNER_HOME /usr/local/sonarscanner/bin/

์–ด์…ˆ๋ธ”๋ฆฌ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ์„ค๋ช…ํ–ˆ๋Š”๋ฐ Jenkins๊ฐ€ ๊ทธ๊ฒƒ๊ณผ ๋ฌด์Šจ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  Jenkins ์—์ด์ „ํŠธ๋Š” ์ด๋Ÿฌํ•œ Docker ์ด๋ฏธ์ง€๋กœ ์ž‘์—…ํ•˜๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

stage("Build project") {
    agent {
        docker {
            image "project-build:${DOCKER_IMAGE_BRANCH}"
            args "-v ${PWD}:/usr/src/app -w /usr/src/app"
            reuseNode true
            label "build-image"
        }
    }
    steps {
        sh "yarn"
        sh "yarn build"
    }
}

์ง€์นจ agent ์žฌ์‚ฐ์„ ์‚ฌ์šฉํ•œ๋‹ค docker๋‹ค์Œ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ช…๋ช… ์ •์ฑ…์— ๋”ฐ๋ฅธ ์–ด์…ˆ๋ธ”๋ฆฌ ์ปจํ…Œ์ด๋„ˆ์˜ ์ด๋ฆ„
  • ๋นŒ๋“œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ธ์ˆ˜์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ ๋นŒ๋“œ ๋‹จ๊ณ„์—์„œ Docker ๋นŒ๋“œ ์—์ด์ „ํŠธ ๋‚ด์—์„œ ์‹คํ–‰ํ•  ๋ช…๋ น์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋ฌด์—‡์ด๋“  ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ansible์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ๋„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์—์„œ๋Š” ๊ฐ„๋‹จํ•œ Node.JS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋ฐ˜ Jenkinsfile์„ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""

pipeline { 
    options {
        buildDiscarder(
            logRotator(
                artifactDaysToKeepStr: "",
                artifactNumToKeepStr: "",
                daysToKeepStr: "",
                numToKeepStr: "10"
            )
        )
        disableConcurrentBuilds()
    }

    agent any

    stages {

        stage("Prepare build image") {
            steps {
                sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
            }
        }

        stage("Build project") {
            agent {
                docker {
                    image "project-build:${DOCKER_IMAGE_BRANCH}"
                    args "-v ${PWD}:/usr/src/app -w /usr/src/app"
                    reuseNode true
                    label "build-image"
                }
            }
            steps {
                sh "yarn"
                sh "yarn build"
            }
        }

    post {
        always {
            step([$class: "WsCleanup"])
            cleanWs()
        }
    }

}

๋ฌด์Šจ ์ผ์ด์—์š”?

์ด ๋ฐฉ๋ฒ• ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ํ™˜๊ฒฝ ์กฐ๋ฆฝ ๊ตฌ์„ฑ ์‹œ๊ฐ„์ด ํ”„๋กœ์ ํŠธ๋‹น 10~15๋ถ„์œผ๋กœ ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค.
  • ์™„์ „ํžˆ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์ถ• ํ™˜๊ฒฝ(๋กœ์ปฌ ์ปดํ“จํ„ฐ์—์„œ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Œ)
  • ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒ„์ „์˜ ์กฐ๋ฆฝ ๋„๊ตฌ ๊ฐ„ ์ถฉ๋Œ๋กœ ์ธํ•œ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ํ•ญ์ƒ ๋ง‰ํžˆ์ง€ ์•Š๋Š” ๊นจ๋—ํ•œ ์ž‘์—… ๊ณต๊ฐ„.

์†”๋ฃจ์…˜ ์ž์ฒด๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๋ช…ํ™•ํ•˜๋ฉฐ ๋ช‡ ๊ฐ€์ง€ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ, ๊ฐ„๋‹จํ•œ ์–ด์…ˆ๋ธ”๋ฆฌ ๋ช…๋ น์— ๋น„ํ•ด ์ง„์ž… ์ž„๊ณ„๊ฐ’์ด ์•ฝ๊ฐ„ ๋†’์•„์กŒ์ง€๋งŒ ์ด์ œ๋Š” ํ•ญ์ƒ ๋นŒ๋“œ๋˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค์— ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ง์ ‘ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ณด์žฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ๊ฐ€ ๋ชจ์€ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค ์  ํ‚จ์Šค + ๋„์ปค. ๋ชจ๋“  ์†Œ์Šค๋Š” ๊ณต๊ฐœ๋˜์–ด ์žˆ์œผ๋ฉฐ ์œ„์น˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. rmuhamedgaliev/jenkins_docker.

์ด ๊ธ€์„ ์ž‘์„ฑํ•˜๋ฉด์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ์Šคํ„ฐ ๋…ธ๋“œ๋ฅผ ๋กœ๋“œํ•˜์ง€ ์•Š๋„๋ก ์›๊ฒฉ ์„œ๋ฒ„์—์„œ ์—์ด์ „ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋„์ปค ํ”Œ๋Ÿฌ๊ทธ์ธ. ํ•˜์ง€๋งŒ ์ด์— ๋Œ€ํ•ด์„œ๋Š” ์•ž์œผ๋กœ ์ด์•ผ๊ธฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€