Learn the importance of newContainerPerStage for stage-level isolation in Jenkins Declarative Pipeline using Dockerfile agents.
In this lesson, you will learn why the newContainerPerStage directive is essential when using a Dockerfile agent in a Jenkins Declarative Pipeline. By default, Jenkins runs all stages in a single container, sharing the workspace and any generated artifacts. We’ll explore both behaviors and show how to enforce stage-level isolation.
When you configure a pipeline with a global Dockerfile agent, every stage executes inside the same container. Artifacts created in one stage remain available in the next:
Copy
Ask AI
pipeline { agent { dockerfile { filename 'Dockerfile.cowsay' label 'ubuntu-docker-jdk17-node20' } } stages { stage('Stage-1') { steps { sh 'cat /etc/os-release' sh 'node -v' sh 'npm -v' echo '#############################' sh "echo $((RANDOM)) > /tmp/imp-file-$BUILD_ID" sh 'ls -ltr /tmp/imp-file-$BUILD_ID' sh 'cat /tmp/imp-file-$BUILD_ID' echo '#############################' } } stage('Stage-2') { steps { sh 'cat /etc/os-release' sh 'node -v' sh 'npm -v' echo 'Reading file generated in Stage-1:' sh 'cat /tmp/imp-file-$BUILD_ID' } } stage('Stage-3') { steps { sh 'cat /etc/os-release' sh 'node -v' sh 'npm -v' } } stage('Stage-4') { steps { sh 'node -v' sh 'npm -v' sh 'cowsay -f dragon This is running on Docker Container' echo 'Final file check:' sh 'cat /tmp/imp-file-$BUILD_ID' sh 'sleep 120s' } } }}
Insert an options block with newContainerPerStage():
Copy
Ask AI
pipeline { agent { dockerfile { filename 'Dockerfile.cowsay' label 'ubuntu-docker-jdk17-node20' } } options { newContainerPerStage() } stages { stage('Stage-1') { steps { sh 'cat /etc/os-release' sh 'node -v' sh 'npm -v' echo '********************' sh "echo $((RANDOM)) > /tmp/imp-file-$BUILD_ID" sh 'ls -ltr /tmp/imp-file-$BUILD_ID' sh 'cat /tmp/imp-file-$BUILD_ID' echo '********************' } } stage('Stage-2') { steps { sh 'cat /etc/os-release' sh 'node -v' sh 'npm -v' echo 'Trying to read file from Stage-1:' sh 'ls -ltr /tmp/imp-file-$BUILD_ID' sh 'cat /tmp/imp-file-$BUILD_ID' } } }}
Now Jenkins rebuilds the Docker image and starts a fresh container for every stage. Stage-2 will fail because the file from Stage-1 no longer exists:
Copy
Ask AI
# Stage-2$ docker build -t pipeline-external-agent -f Dockerfile.cowsay ....# Inside new container$ ls -ltr /tmp/imp-file-9ls: cannot access '/tmp/imp-file-9': No such file or directory
Using newContainerPerStage() increases build time due to repeated image builds. Evaluate the trade-off between isolation and performance.