๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Develop/DevOps

[jenkins] React ํ”„๋กœ์ ํŠธ Docker + jenkins๋กœ CI/CD

by 3-stack 2021. 12. 25.

๐Ÿ“‘ ์  ํ‚จ์Šค ํŠœํ† ๋ฆฌ์–ผ ๋‚ด์šฉ ์ •๋ฆฌ

Node + React ๋กœ ๋งŒ๋“  ์›น์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„

Docker + Jenkins๋กœ CI/CD ํ•ด๋ณด๊ธฐ ์œ„ํ•œ ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ.


1. ๋„์ปค๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

 

2. ๋„์ปค Bridge network ๋ฅผ ๋งŒ๋“ ๋‹ค.

docker network create jenkins

 

3. Jenkins nodes ๋‚ด๋ถ€์—์„œ `Docker commands`๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ `docker:bind` ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์‹คํ–‰.

  • ์‚ฌ์šฉํ•˜๋Š” ํ„ฐ๋ฏธ๋„์— ๋”ฐ๋ผ ์ปค๋งจ๋“œ ๊ฐœํ–‰ ๋ฌธ์ž๊ฐ€ ๋‹ค๋ฆ„.
    bash - \, powershell - `, ๋ช…๋ นํ”„๋กฌํŠธ - ^
  • Windows์˜ ๊ฒฝ์šฐ ์‹คํŒจ์‹œ 13๋ฒˆ ์ƒ๋žตํ•ด๋ณด์„ธ์š”.

๋”๋ณด๊ธฐ
๋”๋ณด๊ธฐ
docker run \ --name jenkins-docker \ --rm \ --detach \ --privileged \ --network jenkins \ --network-alias docker \ --env DOCKER_TLS_CERTDIR=/certs \ --volume jenkins-docker-certs:/certs/client \ --volume jenkins-data:/var/jenkins_home \ --publish 3000:3000 \ --publish 2376:2376 \ docker:dind \ --storage-driver overlay2
  1. ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„ ์ง€์ •.
  2. ์ข…๋ฃŒ๋˜๋ฉด ์ปจํ…Œ์ด๋„ˆ ์ž๋™ ์ œ๊ฑฐ.
  3. ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰. ์ปจํ…Œ์ด๋„ˆ ID๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์˜ต์…˜์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ํ˜„์žฌ ํ„ฐ๋ฏธ๋„์ฐจ์— ๋„์ปค ๋กœ๊ทธ ์ถœ๋ ฅ.
  4. Docker-in-Docker ์ •์ƒ ์ž‘๋™ ์œ„ํ•ด์„œ ๊ถŒํ•œ ๋ถ€์—ฌ.
  5. ์•ž์„œ ์ƒ์„ฑํ•œ "jenkins"๋ผ๋Š” ์ด๋ฆ„์˜ ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ.
  6. "jenkins" ๋„คํŠธ์›Œํฌ์—์„œ `Docker ์ปจํ…Œ์ด๋„ˆ` ๋‚ด๋ถ€์˜ `Docker`๋ฅผ "docker"๋ผ๋Š” ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉ.
  7. Docker ์„œ๋ฒ„์—์„œ TLS ์‚ฌ์šฉ์„ ํ™œ์„ฑํ™”ํ•œ๋‹ค. ๊ถŒํ•œ ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ถŒ์žฅ๋œ๋‹ค. ์•„๋ž˜์— ์„ค๋ช…๋œ ๊ณต์œ  ๋ณผ๋ฅจ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์ด ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” Docker TLS ์ธ์ฆ์„œ๊ฐ€ ๊ด€๋ฆฌ๋˜๋Š” ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ œ์–ดํ•œ๋‹ค.
  8. ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์˜ /certs/client ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ jenkins-docker-certs๋ผ๋Š” Docker ๋ณผ๋ฅจ์— ๋งคํ•‘ํ•œ๋‹ค. jenkins-docker-certs ๋ณผ๋ฅจ์ด ์—†์œผ๋ฉด ์ƒ์„ฑํ•œ๋‹ค.
  9. ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์˜ /var/jenkins_home ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ jenkins-data๋ผ๋Š” Docker ๋ณผ๋ฅจ์— ๋งคํ•‘ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `Docker ์ปจํ…Œ์ด๋„ˆ์˜ Docker ๋ฐ๋ชฌ`์ด ์ œ์–ดํ•˜๋Š” `โ€‹โ€‹๋‹ค๋ฅธ Docker ์ปจํ…Œ์ด๋„ˆ`๊ฐ€ Jenkins์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํƒ‘์žฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  10. Docker ๋ฐ๋ชฌ ํฌํŠธ๋ฅผ ๋…ธ์ถœํ•œ๋‹ค.
  11. ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ Docker ๋ฐ๋ชฌ ํฌํŠธ๋ฅผ ๋…ธ์ถœํ•œ๋‹ค. ๋‚ด๋ถ€ Docker ๋ฐ๋ชฌ์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์—์„œ docker ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค.
  12. docker:dinder ์ด๋ฏธ์ง€ ์ž์ฒด. ์ด ์ด๋ฏธ์ง€๋Š” docker image pull docker:dind ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ๊ณต์‹ Jenkins ๋„์ปค ์ด๋ฏธ๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•œ๋‹ค.

  4-1. ๋‹ค์Œ๊ณผ ๊ฐ™์ด `Dockerfile`์„ ๋งŒ๋“ ๋‹ค.

FROM jenkins/jenkins:2.319.1-jdk11
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
  https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
  https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean:1.25.2 docker-workflow:1.26"

   4-2. `Dockerfile`๋กœ ์ƒˆ๋กœ์šด ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ ๋‹ค.

docker build -t myjenkins-blueocean:1.1 .

 

5. ๋งŒ๋“  `myjenkins-blueocean:1.1` ์ด๋ฏธ์ง€๋ฅผ ์ปจํ…Œ์ด๋„ˆ๋กœ ์‹คํ–‰.

  • 10๋ฒˆ์˜ ๊ฒฝ๋กœ๋Š” ํ˜„์žฌ ์‚ฌ์šฉ์ž ํด๋”๋ฅผ ๊ฐ€๋ฅดํ‚จ๋‹ค. => /c/Users/{์‚ฌ์šฉ์ž๋ช…} 
  • Host์™€ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ๊ฒฝ๋กœ๋ฅผ ๋งํฌ๊ฑธ๊ฒŒ ๋˜๋ฏ€๋กœ ๊ถŒํ•œ์ด ํ•„์š”ํ•˜๋‹ค. ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์‹คํ–‰.
  • Windows์˜ ๊ฒฝ์šฐ 10๋ฒˆ = --volume "%HOMEDRIVE%%HOMEPATH%":/home
  • ๋กœ์ปฌ์— Jenkins๋ฅผ 8080 ํฌํŠธ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ, 6๋ฒˆ ํฌํŠธ๋ฅผ ๋ณ€๊ฒฝํ•ด์„œ ๋งํฌํ•˜์ž.(8888:8080)

๋”๋ณด๊ธฐ
๋”๋ณด๊ธฐ
docker run \ --name jenkins-blueocean \ --rm \ --detach \ --network jenkins \ --env DOCKER_HOST=tcp://docker:2376 \ --env DOCKER_CERT_PATH=/certs/client \ --env DOCKER_TLS_VERIFY=1 \ --publish 8080:8080 \ --publish 50000:50000 \ --volume jenkins-data:/var/jenkins_home \ --volume jenkins-docker-certs:/certs/client:ro \ --volume "$HOME":/home \ myjenkins-blueocean:1.1
  1. ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„ ์ง€์ •.
  2. ์ข…๋ฃŒ๋˜๋ฉด ์ปจํ…Œ์ด๋„ˆ ์ž๋™ ์ œ๊ฑฐ.
  3. ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰. ์ปจํ…Œ์ด๋„ˆ ID๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์˜ต์…˜์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ํ˜„์žฌ ํ„ฐ๋ฏธ๋„์ฐจ์— ๋„์ปค ๋กœ๊ทธ ์ถœ๋ ฅ.
  4. ์ด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ด์ „ ๋‹จ๊ณ„์—์„œ ์ •์˜ํ•œ "jenkins" ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ "docker"๋ฅผ ํ†ตํ•ด ์ด Jenkins ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ด์ „ ๋‹จ๊ณ„์˜ Docker ๋ฐ๋ชฌ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  5. ์ด์ „ ๋‹จ๊ณ„์—์„œ ์ƒ์„ฑํ•œ Docker ๋ฐ๋ชฌ์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด docker, docker-compose ๋ฐ ๊ธฐํƒ€ Docker ๋„๊ตฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •.
  6. ํ˜„์žฌ ์ปจํ…Œ์ด๋„ˆ์˜ ํฌํŠธ 8080์„ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ ํฌํŠธ 8080์— ๋งคํ•‘.
    ์ฒซ ๋ฒˆ์งธ ์ˆซ์ž๋Š” ํ˜ธ์ŠคํŠธ์˜ ํฌํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ  ๋งˆ์ง€๋ง‰ ์ˆซ์ž๋Š” ์ปจํ…Œ์ด๋„ˆ์˜ ํฌํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    ๋”ฐ๋ผ์„œ ์ด ์˜ต์…˜์— -p 49000:8080์„ ์ง€์ •ํ•˜๋ฉด ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์—์„œ ํฌํŠธ 49000์„ ํ†ตํ•ด  Jenkins์— ์•ก์„ธ์Šคํ•˜๊ฒŒ ๋œ๋‹ค.
  7. ํ˜„์žฌ ์ปจํ…Œ์ด๋„ˆ์˜ ํฌํŠธ 50000์„ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ ํฌํŠธ 50000์— ๋งคํ•‘.
    ์ด๋Š” ๋‹ค๋ฅธ ๋จธ์‹ ์— ํ•˜๋‚˜ ์ด์ƒ์˜ ์ธ๋ฐ”์šด๋“œ Jenkins ์—์ด์ „ํŠธ๋ฅผ ์„ค์ •ํ•œ ๊ฒฝ์šฐ์—๋งŒ ํ•„์š”ํ•˜๋ฉฐ, ์ด๋Š” ์ฐจ๋ก€๋กœ jenkins-blueocean ์ปจํ…Œ์ด๋„ˆ(Jenkins "์ปจํŠธ๋กค๋Ÿฌ")์™€ ์ƒํ˜ธ ์ž‘์šฉํ•œ๋‹ค.
    ์ธ๋ฐ”์šด๋“œ Jenkins ์—์ด์ „ํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ TCP ํฌํŠธ 50000์„ ํ†ตํ•ด Jenkins ์ปจํŠธ๋กค๋Ÿฌ์™€ ํ†ต์‹ ํ•œ๋‹ค. ๊ธ€๋กœ๋ฒŒ ๋ณด์•ˆ ๊ตฌ์„ฑ ํŽ˜์ด์ง€๋ฅผ ํ†ตํ•ด Jenkins ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ด ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  8. ์ปจํ…Œ์ด๋„ˆ์˜ /var/jenkins_home ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ jenkins-data๋ผ๋Š” ์ด๋ฆ„์˜ Docker ๋ณผ๋ฅจ์— ๋งคํ•‘ํ•œ๋‹ค.
    /var/jenkins_home ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ Docker ๋ณผ๋ฅจ์— ๋งคํ•‘ํ•˜๋Š” ๋Œ€์‹  ์ด ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ Host์˜ ๋กœ์ปฌ ํŒŒ์ผ ์‹œ์Šคํ…œ์— ๋งคํ•‘ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์˜ต์…˜ ์ง€์ • `--volume $HOME/jenkins:/var/jenkins_home`๋Š”  Host์˜ $HOME ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” jenkins ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ(์ผ๋ฐ˜์ ์œผ๋กœ /Users/<your-username>/jenkins ๋˜๋Š” /home/<์‚ฌ์šฉ์ž ์ด๋ฆ„>/jenkins)๋กœ ๋งคํ•‘ํ•œ๋‹ค. ์ด์— ๋Œ€ํ•œ ์†Œ์Šค ๋ณผ๋ฅจ ๋˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ ์œ„์˜ docker:dind ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋ณผ๋ฅจ์„ ์ด์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  9. /certs/client ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ด์ „์— ์ƒ์„ฑ๋œ jenkins-docker-certs ๋ณผ๋ฅจ์— ๋งคํ•‘ํ•œ๋‹ค.
    ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด DOCKER_CERT_PATH ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ง€์ •๋œ ๊ฒฝ๋กœ์—์„œ Docker ๋ฐ๋ชฌ์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ํด๋ผ์ด์–ธํŠธ TLS ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  10. ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ $HOME ๋””๋ ‰ํ† ๋ฆฌ(์ผ๋ฐ˜์ ์œผ๋กœ /Users/<your-username> ๋””๋ ‰ํ† ๋ฆฌ)๋ฅผ ์ปจํ…Œ์ด๋„ˆ์˜ /home ๋””๋ ‰ํ† ๋ฆฌ์— ๋งคํ•‘ํ•œ๋‹ค.
  11. ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋นŒ๋“œํ•œ Docker ์ด๋ฏธ์ง€์˜ ์ด๋ฆ„์ด๋‹ค.

 

6. Jenkins ์„ค์ •

  • ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ(๊ฒฝ๋กœ ์˜ˆ์‹œ: c/Users/{์‚ฌ์šฉ์ž๋ช…}/dev/node-react-jenkins/simple-node-js-react-npm-app)
  • Jenkins ์ ‘์†(localhost:8080)
    • ํ™”๋ฉด์— ํ‘œ์‹œ๋œ ๊ฒฝ๋กœ์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅํ•˜๊ณ  ๋กœ๊ทธ์ธ
    • ์ƒˆ๋กœ์šด Item > ํŒŒ์ดํ”„๋ผ์ธ ๋งŒ๋“ค๊ธฐ
  • Jenkins ํŒŒ์ดํ”„๋ผ์ธ ์„ค์ • ( /home = /c/Users/{์‚ฌ์šฉ์ž๋ช…} )

 

7. Jenkins script

pipeline {
    agent {
        docker {
            image 'node:lts-buster-slim'
            args '-p 3000:3000'
        }
    }
    environment {
        CI = 'true'
    }
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
            }
        }
        stage('Test') {
            steps {
                sh './jenkins/scripts/test.sh'
            }
        }
        stage('Deliver') {
            steps {
                sh './jenkins/scripts/deliver.sh'
                input message: 'Finished using the web site? (Click "Proceed" to continue)'
                sh './jenkins/scripts/kill.sh'
            }
        }
    }
}

๋Œ“๊ธ€