react/vue.js의 CI/CD 속도 높이기
react나 vue.js를 Jenkins 파이프라인으로 CI/CD할 때 아래 예제와 같이 library를 install할 때 매우 시간이 걸립니다.
이를 NFS(Network file server)의 volume을 이용하여 개선하는 방법입니다.
예제는 아래 git repository의 deployment디렉토리 하위에 있는 Dockerfile-cicid와 Jenkinsfile을 참조 하십시오.
https://github.com/happykubepia/react-weather-app.git
아래와 같은 순서로 작업 하시면 됩니다.
package.json의 build명령 수정
package.json파일의 "scripts"."build"의 명령 앞에 'CI= '을 추가하셔야 합니다.
이걸 안 하면 Jenkins pipeline에서 'yarn build'나, 'npm run build' 시 compile error가 발생합니다.
react는 'CI= react-scripts build'로 수정하시면 됩니다.
vue.js는 'CI= vite build'로 수정하시면 됩니다.
Jenskindfile 수정
Jenkins agent Pod안에 node.js 컨테이너를 추가합니다.
podTemplate(
label: label,
containers: [
containerTemplate(name: "node", image: "node:alpine", ttyEnabled: true, command: "cat"),
...
]
NFS서버의 특정 디렉토리를 npm과 yarn의 캐싱 디렉토리로 마운트 합니다.
NFS서버의 IP와 볼륨 디렉토리는 자신에 맞게 수정해야 합니다.
podTemplate(
label: label,
...
//volume mount
volumes: [
nfsVolume( mountPath: '/root/.npm', serverAddress: '10.193.24.247', serverPath: '/users/data/jenkins/.npm', readOnly: false ),
nfsVolume( mountPath: '/root/.yarn', serverAddress: '10.193.24.247', serverPath: '/users/data/jenkins/.yarn', readOnly: false )
]
)
기존에 Dockerfile내에서 하던 Script build를 이제 Jenkins pipeline에서 하도록 Stage를 추가 합니다.
'yarn install'하면서 cache 디렉토리를 지정 합니다.
yarn install 시 특정 디렉토리 밑에 소스가 있는 경우 yarn build --module_folder {디렉토리명}을 사용 하십시오.
npm install이나 npm run build 시 특정 디렉토리 밑에 소스가 있는 경우는 --prefix파라미터를 사용하시면 됩니다.
특정 디렉토리 밑에 있지 않고 최상위 디렉토리에 소스가 있다면 지정 않하셔도 됩니다.
stage("Build React Scripts") {
container("node") {
sh "yarn install --cache-folder /root/.yarn"
sh "npm install"
sh "npm run build"
}
}
* Typescript로 개발하는 경우 아래 명령도 추가 하셔야 build가 제대로 됩니다.
sh "npm i --save-dev @types/styled-components"
Container image를 Build할 때 사용하는 Dockerfile을 새로 만든 'Dockerfile-cicd'로 변경 합니다.
이 파일은 바로 아래에서 설명합니다.
stage("Build Container image") {
container("podman") {
withCredentials([usernamePassword(
credentialsId: "${credentialRegistry}",
usernameVariable: 'USER',
passwordVariable: 'PASSWORD'
)]) {
sh 'echo user "$USER" pasword "$PASSWORD"'
sh "podman login ${registry} --username ${USER} --password ${PASSWORD}"
sh "podman build -f ./deployment/Dockerfile-cicd -t ${registry}/${organization}/${repository}:${tag} ."
sh "sleep 2"
sh "podman push ${registry}/${organization}/${repository}:${tag}"
sh "podman tag ${registry}/${organization}/${repository}:${tag} ${registry}/${organization}/${repository}:latest"
sh "podman push ${registry}/${organization}/${repository}:latest"
}
}
}
Dockerfile-cicd 생성
Jenkins 파이프라인에서 Script build를 하기 때문에 Dockerfile에서는 빌드된 script를 container image안으로 복사하는 작업만 해주면 됩니다.
아래와 같이 작성하시면 됩니다.
FROM nginx:latest
COPY ./build /usr/share/nginx/html
## Copy web configuration
COPY ./deployment/default.conf.template /etc/nginx/conf.d/default.conf
#
## 80포트 오픈하고 nginx 실행
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
참고) Jenkins pipeline을 실행하고 NFS volueme(위 예에서는 /users/data/jenkins)을 보면 아래 예와 같이 디렉토리가 생깁니다.
Jenkins agent pod의 volume과 연결되었기 때문입니다.
drwxrwxrwx. 4 kbdemobastion kbdemobastion 4096 12월 19 22:56 .npm
drwxrwxrwx. 3 kbdemobastion kbdemobastion 4096 12월 19 23:05 .yarn