Habrรฉ์๋ Jenkins์ ๋ํ ๊ธฐ์ฌ๊ฐ ๋ง์ด ์์ง๋ง Jenkins์ Docker ์์ด์ ํธ๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ํ ์๋ฅผ ์ค๋ช
ํ๋ ๊ธฐ์ฌ๋ ๊ฑฐ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๋ชจ๋ ์ธ๊ธฐ ์๋ ํ๋ก์ ํธ ๋น๋ ๋๊ตฌ
์ค๋๋ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ
์ด ์์ต๋๋ค. Jenkins 2๋ ์์
์ ํ์ํฉ๋๋ค.
์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์์ํ์ต๋๊น?
์ฐ๋ฆฌ๋ ํ์ฌ์ ์๊ธฐ ๋๋ฌธ์
- ๊ฐ๋ฐ์๊ฐ ์ ๋ฆฌํ๋ ๊ฒ์ ์์ด๋ฒ๋ฆฐ ๋ง์ ์์ ๋ฐํ์;
- ๋์ผํ ๋ฐํ์์ ์๋ก ๋ค๋ฅธ ๋ฒ์ ๊ฐ์ ์ถฉ๋์ด ์์ต๋๋ค.
- ๋ชจ๋ ๊ฐ๋ฐ์์๊ฒ๋ ์๋ก ๋ค๋ฅธ ๊ตฌ์ฑ ์์ ์ธํธ๊ฐ ํ์ํฉ๋๋ค.
๋ค๋ฅธ ๋ฌธ์ ๋ ์๋๋ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์๋ ค๋๋ฆฌ๊ฒ ์ต๋๋ค.
๋์ปค์ ์ ํจ์ค
Docker๋ ์ด์ ๊ฐ๋ฐ ํ๊ฒฝ์์ ์ ์๋ฆฌ์ก์๊ธฐ ๋๋ฌธ์ Docker๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฑฐ์ ๋ชจ๋ ๊ฒ์ ์คํํ ์ ์์ต๋๋ค. ๋ด ์๋ฃจ์
์ Docker์ Jenkins๋ฅผ ๋๊ณ ๋ค๋ฅธ Docker ์ปจํ
์ด๋๋ฅผ ์คํํ ์ ์๊ฒ ํ๋ ๊ฒ์
๋๋ค. ์ด ์ง๋ฌธ์ 2013๋
์ โ
์ฆ, ์์
์ปจํ
์ด๋์ 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๋ถ์ผ๋ก ๋จ์ถ๋ฉ๋๋ค.
- ์์ ํ ๋ฐ๋ณต ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ ํ๊ฒฝ(๋ก์ปฌ ์ปดํจํฐ์์ ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๊ตฌ์ถํ ์ ์์)
- ์๋ก ๋ค๋ฅธ ๋ฒ์ ์ ์กฐ๋ฆฝ ๋๊ตฌ ๊ฐ ์ถฉ๋๋ก ์ธํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
- ํญ์ ๋งํ์ง ์๋ ๊นจ๋ํ ์์ ๊ณต๊ฐ.
์๋ฃจ์ ์์ฒด๋ ๊ฐ๋จํ๊ณ ๋ช ํํ๋ฉฐ ๋ช ๊ฐ์ง ์ด์ ์ ์ป์ ์ ์์ต๋๋ค. ์, ๊ฐ๋จํ ์ด์ ๋ธ๋ฆฌ ๋ช ๋ น์ ๋นํด ์ง์ ์๊ณ๊ฐ์ด ์ฝ๊ฐ ๋์์ก์ง๋ง ์ด์ ๋ ํญ์ ๋น๋๋๊ณ ๊ฐ๋ฐ์๊ฐ ๋น๋ ํ๋ก์ธ์ค์ ํ์ํ ๋ชจ๋ ๊ฒ์ ์ง์ ์ ํํ ์ ์๋ค๋ ๋ณด์ฅ์ด ์์ต๋๋ค.
์ ๊ฐ ๋ชจ์ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํด๋ ๋ฉ๋๋ค
์ด ๊ธ์ ์์ฑํ๋ฉด์ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ์ฌ ๋ง์คํฐ ๋
ธ๋๋ฅผ ๋ก๋ํ์ง ์๋๋ก ์๊ฒฉ ์๋ฒ์์ ์์ด์ ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ํ ๋
ผ์๊ฐ ์์์ต๋๋ค.
์ถ์ฒ : habr.com