배경: Jenkins는 훌륭하게 작동하는 docker 컨테이너 내에서 실행되지만, 설계상 Jenkins 컨테이너 내부에 설치된 소프트웨어를 최소화하기 위해 모든 빌드 프로세스가 docker 컨테이너 내에서 실행되기를 원합니다.
문제: 세 단계가 모두 파일을 공유하는 두 개의 다른 도커 컨테이너를 사용하여 3단계 프로세스를 어떻게 구축합니까?
1단계: 빌드
- npm 빌드
2단계: 테스트
- npm 테스트`
3단계: AWS 코드 배포 실행
- aws 배포 푸시 --application-name app-name --s3-location s3://my-bucket/app-name --ignore-hidden-files
- aws 배포 create-deployment --application-name 앱 이름 --s3-location bucket=my-bucket,key=app-name,bundleType=zip --deployment-group-name dg
Jenkins 파일을 여러 단계로 나누고 첫 번째 단계의 출력을 다른 단계에 공유하려면 어떻게 해야 합니까?
간단한 2단계 Jenkinsfile
pipeline {
agent {
docker {
image 'node:10.8.0'
}
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
그런데 세 번째 단계에 추가하면 전역 도커 이미지(에이전트)를 사용할 수 없기 때문에 상황이 더욱 흥미로워집니다.
pipeline {
agent none
stages {
stage('Build') {
agent {
docker { image 'node:10.8.0' }
}
steps {
sh 'npm install'
}
}
stage('Test') {
agent {
docker { image 'node:10.8.0' }
}
steps {
sh 'npm test'
}
}
stage('Deploy') {
agent {
docker { image 'coreos/awscli' }
}
steps {
sh 'echo "Deploying to AWS"'
sh 'aws help'
}
}
}
}
위의 경우 빌드 단계의 결과가 손실되어 'npm test'가 실패합니다. 그리고 모든 빌드 아티팩트가 손실되므로 코드 배포가 작동하지 않습니다.
테스트 작업을 위한 한 가지 해결 방법은 이미지를 사용하는 'BuildAndTest' 단계를 갖는 것이지만, 이렇게 하면 별도 단계의 장점 중 일부가 손실됩니다.
pipeline {
agent none
stages {
stage('Build And Test') {
agent {
docker { image 'node:10.8.0' }
}
steps {
sh 'npm install'
sh 'npm test'
}
}
stage('Deploy') {
agent {
docker { image 'coreos/awscli' }
}
steps {
sh 'echo "Deploying to AWS"'
sh 'aws help'
}
}
}
}
또 다른 (아주 추악한) 해결책은 node와 aws가 모두 설치된 사용자 정의 이미지를 생성하는 것입니다. 그러나 이는 노드 및/또는 aws의 최신 버전으로 마이그레이션할 때마다 업데이트된 버전으로 또 다른 도커 이미지를 생성해야 함을 의미합니다. , 실제로는 완전히 별개의 작업입니다.
다른 해결책은 모든 인스턴스 간에 공유 이미지를 마운트하는 것입니다. 하지만 이 빌드에만 공유되고 빌드가 완료된 후 삭제되는 '임시' 이미지를 만들려면 어떻게 해야 합니까?
답변1
질문을 게시한 직후 Jenkins 개발자의 기사를 발견했습니다.
https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-series-stages/
이것이 내가 생각해낸 것이다
pipeline {
agent none
stages {
stage('Build and Test') {
agent {
docker 'node:10.8.0'
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
post {
success {
stash name: 'artifacts', includes: "node_modules/**/*"
}
}
}
stage('Deploy') {
agent {
docker 'coreos/awscli'
}
steps {
unstash 'artifacts'
sh 'echo "Deploying to AWS"'
sh 'aws help'
}
}
}
}
Jenkins는 이제 선언문 내에서 여러 단계를 허용하며 나에게 매우 효과적인 'stash/unstash' 명령에 대해 몰랐습니다.