📦 ETC/그냥 쓰고 싶어서요

[Jenkins] CentOS6에서 nvm 사용 시 node-error가 발생할 때

1HOON 2022. 12. 21. 01:39

많은 서비스에서 CI/CD(Continuous Integration/Continuous Delivery, 지속적 통합/지속적 제공) 도구로 Jenkins를 사용합니다.

그중에서도 npm을 통해 의존성 패키지를 관리하는 프로젝트를 빌드하고 배포하는 경우가 있는데요, NVM(Node Version Manager)이라는 도구를 사용해 각 파이프라인별로 Node.js의 버전을 다르게 사용할 수 있습니다.

 

이번 포스팅에서는 그동안 잘 되고 있던 파이프라인에서 갑자기 발생한 node-error 오류와 그 오류를 해결하는 과정을 공유하고자 합니다.

(문제가 발생하기 전 마지막 빌드가 반년 전인건 비밀...)

 

환경 🖥️


  • OS : CentOS 6.8
  • Jenkins 2.263.3
  • nvm-wrapper 0.1.7
  • npm을 사용하는 프로젝트

 

 

 

오류 내용 📃


실패한 Job의 로그에는 아래와 같은 내용이 포함되어 있었습니다.

+++ npm config get prefix
node: /usr/lib64/libstdc++.so.6: version GLIBCXX_3.4.14' not found (required by node)
node: /usr/lib64/libstdc++.so.6: version GLIBCXX_3.4.18' not found (required by node)
node: /usr/lib64/libstdc++.so.6: version CXXABI_1.3.5' not found (required by node)
node: /usr/lib64/libstdc++.so.6: version GLIBCXX_3.4.15' not found (required by node)
node: /lib64/libc.so.6: version GLIBC_2.16' not found (required by node)
node: /lib64/libc.so.6: version GLIBC_2.17' not found (required by node)
node: /lib64/libc.so.6: version GLIBC_2.14' not found (required by node)
++ NVM_NPM_PREFIX=
++ nvm_tree_contains_path /home/centos/.nvm ''
++ '[' _0 = _1 ']'
++ nvm deactivate
++ nvm_err 'nvm is not compatible with the npm config "prefix" option: currently set to ""'
++ nvm_echo 'nvm is not compatible with the npm config "prefix" option: currently set to ""'
++ command printf '%s\n' 'nvm is not compatible with the npm config "prefix" option: currently set to ""'
nvm is not compatible with the npm config "prefix" option: currently set to ""
++ nvm_has npm
++ type npm
++ nvm_err 'Run nvm use --delete-prefix v12.22.12 --silent to unset it.'
++ nvm_echo 'Run nvm use --delete-prefix v12.22.12 --silent to unset it.'
++ command printf '%s\n' 'Run nvm use --delete-prefix v12.22.12 --silent to unset it.'
Run nvm use --delete-prefix v12.22.12 --silent` to unset it.
++ return 10
++ return 11

 

 

 

Deep Dive 🤔


오류가 발생한 이유를 알기 위해서는 NVM이 무엇인지, 또 어떤 역할을 해주고 있는지, npm과는 무슨 연관이 있는지 우선 알아야 했습니다.

 

 

NVM(Node Version Manager)이란?


Jenkins 서버에서 여러 개의 파이프라인을 빌드하는데, 새로운 파이프라인 때문에 Node.js 버전을 업데이트한다고 생각해봅시다.

이 경우 업데이트된 Node.js의 버전은 모든 파이프라인에 영향을 주게 될 것입니다. 그렇게 되면 구현 당시 예상했던 빌드 결과와는 다른 결과를 초래할 수도 있습니다.

 

때문에 같은 서버에서 여러 개의 Node.js 버전을 사용할 수 있게 해주는 NVM(Node Version Manager)이 등장했습니다.

 

NVM은 다음과 같은 기능을 제공합니다.

  • 간단한 커멘드로 Node.js의 LTS 버전을 로컬로 다운로드할 수 있습니다.
  • 커멘드로 Node.js의 버전을 손쉽게 변경할 수 있습니다.
  • 알리아스를 지정해 Node.js의 버전을 손쉽게 변경할 수 있습니다.

그렇다면 NVM은 어떻게 설치하고 사용할 수 있을까요?

설치

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

사용법

아래 커멘드로 특정 버전의 Node.js를 설치할 수 있습니다.

nvm install [노드 버전]

아래 커멘드로 최신 버전의 Node.js를 설치할 수 있습니다.

nvm install node

그리고 특정 버전의 Node.js를 사용하기 위해서는 아래 커멘드를 수행하면 됩니다.

nvm use [노드 버전]

 

그렇다면 Jenkins에서는 이 NVM을 어떻게 사용할까요?

 

 

Jenkins에서 NVM 사용하기


방법 1 : mvn-warpper (추천)

Jenkins에서는 nvm-wrapper라는 플러그인을 통해 사용할 수 있습니다.

플러그인 설치는 세 가지 방법이 존재하며, 아래와 같습니다. (사실 GUI를 사용하는 것이 가장 간편합니다.)

  1. GUI를 통한 설치
    Jenkins 관리 > Manage Plugins > Available 탭 선택 > nvm-wrapper 검색 및 설치
  2. CLI 툴을 통한 설치
    jenkins-plugin-cli --plugins nvm-wrapper:0.1.7
  3. 직접 다운로드해 업로드
    링크를 통해 릴리즈 된 파일을 다운로드하고 Jenkins에 업로드

 

플러그인 설치 후에는 Node.js 버전 관리가 필요한 파이프라인의 구성 화면으로 접근합니다.

빌드 환경 탭에서 Run thie build in an NVM managed environment 옵션을 체크하면 아래와 같은 입력 폼이 노출됩니다.

  • Node version : 사용할 Node.js의 버전을 입력합니다.
  • NVM_DIR installation dir : NVM이 설치된 디렉터리 경로를 입력합니다. .nvm으로 끝나야 합니다.

 

방법 2 : Execute Shell

NVM을 수동으로 설치한 경우(mvn-wrapper 플러그인 미설치 시) 사용하는 방법입니다.

Pre Steps 탭에서 Execute Shell 테스크를 추가합니다. 그리고 해당 테스크의 쉘 스크립트로 아래와 같이 입력합니다.

# immediate script fail off, echo off
set +ex

# set local path to NVM
export NVM_DIR="$HOME/.nvm" 

# This loads nvm(add NVM into the Shell session)
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" 

# Node.js 설치
nvm install [노드 버전]

# Node.js 버전 선택
nvm use [노드 버전]

# immediate script fail on (default), echo on
set -ex

Jenkins Job에서 쉘 스크립트를 실행할 때, non-interactive session을 사용하기 때문에 .profile 이나 .bashrc 이 모두 실행되지 않습니다. 때문에 nvm 커멘드 또한 자동으로 설정되지 않습니다.

 

게다가 nvm.sh 가 0이 아닌 종료 상태를 반환하는 경우 젠킨스 작업은 실패합니다. 그래서 전체 스크립트 앞뒤로 -e 쉘 옵션을 통해 그것을 잠시 꺼두는 것입니다.

 

이렇게 해서 NVM이 무엇이고, 어떻게 사용하는 것인지 알게 되었습니다.

그렇다면 앞서 발생한 오류는 왜 발생했을까요?

 

 

 

오류의 원인 찾기 👀


mvn-wrapper 플러그인 확인


먼저 Jenkins에 nvm-warpper 플러그인이 설치되어있는지 확인해보았습니다.

확인 결과 해당 플러그인이 설치되어있었습니다.

 

 

파이프라인 mvn 설정 확인


그다음으로는 오류가 발생한 파이프라인의 NVM 관련 설정을 확인해보았습니다.

그런데, 앞서 소개해드린 방법 중 두 번째 방법인 Pre Steps > Execute Shell 방식으로 설정이 되어있었습니다.

그리고 Node.js의 버전은 6.4.0으로 세팅되어있었습니다.

 

 

성공 로그 확인


가장 최근에 빌드에 성공한 Build History의 로그를 확인해보았습니다.

그런데! 이때 Node.js의 버전은 v8.10.0이었습니다.

 

그 말은 기존의 NVM 관련 설정이 정상적으로 동작하지 않았다는 뜻이었습니다.

 

 

실패 로그 확인


실패한 로그를 다시 한번 확인해보았습니다.

마찬가지로 사용된 Node.js의 버전은 파이프라인에 설정된 v6.4.0이 아닌 v12.22.12이었습니다.

 

그리고 오류 로그 중 node: /usr/lib64/libstdc++.so.6: version GLIBCXX_3.4.14' not found (required by node) 로 검색을 해보니, Node.js 12 버전에서 요구하는 의존성의 버전이 현재 Jenkins 서버에 있는 것보다 높아서 발생한 것이었습니다.

 

 

의존성 버전 확인


현재 Jenkins 서버에 설치된 의존성 버전을 확인해보니 각각 다음과 같았습니다.

  • gcc : 4.x.x
  • GLIBC : 2.x.x
  • GLIBCXX : 3.x.x

그리고 Node.js v12.22.12에서 요구하는 버전은 아래와 같았습니다.

  • gcc : 6.3.x ~
  • GLIBC : 2.14 ~ 2.17
  • GLIBCXX : 3.4.14 ~ 3.4.18

 

 

정리해보면


  1. 기존의 NVM 관련 설정이 정상적이지 않았다.
  2. 때문에 빌드할 때마다 최신 버전의 Node.js를 설치하고 사용해왔었다.
  3. 그동안은 문제없었지만, 실패한 시점에서 설치된 Node.js 버전의 의존성을 충족시키지 못해 오류가 발생했다.

 

 

해결 🛠️


그렇다면 해결 방법은 크게 두 가지가 있겠습니다.

  1. NVM 설정을 수정해준다.
  2. 필요한 의존성을 업데이트해 만족시켜준다.

두 번째 방법은 결국에 다른 파이프라인에서도 같은 문제가 언젠가는 발생할 수 있고, NVM을 사용하지 않은 것과 같은 결과였기 때문에 첫 번째 방법으로 NVM 설정을 수정하기로 했습니다.

 

파이프라인의 NVM 설정을 mvn-wrapper 플러그인을 사용하는 방식으로 변경해 정상적으로 빌드에 성공했습니다.

 

 

 

References


 

What is NVM?

Contributor: Educative Answers Team

www.educative.io

 

nvm-wrapper

NVM wrapper plugin

plugins.jenkins.io

 

Using NVM with Jenkins — СЮМ

Imagine that we need to update Node.js version on the Jenkins server. But it could affect other projects. For such cases, when we need multiple versions of Node.js on the same server the NVM (Node Version Manager) project exist. NVM Documentations - https:

yura.stryi.com

반응형