Pipeline Using Docker
You’re now ready to create your Pipeline that will automate building your Node.js and React application in Jenkins. Your Pipeline will be created as a Jenkinsfile
, which will be committed to your locally cloned Git repository (simple-node-js-react-npm-app
).
This is the foundation of "Pipeline-as-Code", which treats the continuous delivery pipeline as a part of the application to be versioned and reviewed like any other code. Read more about Pipeline and what a Jenkins file is in the Pipeline and Using a Jenkins file sections of the User Handbook.
First, create an initial Pipeline to download a Node Docker image and run it as a Docker container (which will build your simple Node.js and React application). Also add a "Build" stage to the Pipeline that begins orchestrating this whole process.
Using your favorite text editor or IDE, create and save new text file with the name
Jenkinsfile
at the root of your localsimple-node-js-react-npm-app
Git repository.Copy the following Declarative Pipeline code and paste it into your empty
Jenkinsfile
:
This image parameter (of the agent section’s docker parameter) downloads the node latest Docker image (if it’s not already available on your machine) and runs this image as a separate container. This means that: You’ll have separate Jenkins and Node containers running locally in Docker. The Node container becomes the agent that Jenkins uses to run your Pipeline project. However, this container is short-lived - its lifespan is only that of the duration of your Pipeline’s execution.
This args parameter makes the Node container (temporarily) accessible through port 3000. The significance of this is explained in the jenkins/scripts/deliver.sh file of your cloned repository, and is covered in a subsequent section of this tutorial.
Defines a stage (directive) called Build that appears on the Jenkins UI.
This sh step (of the steps section) executes the npm command to ensure that all dependencies required to run your application have been downloaded to the node_modules workspace directory (within the /var/jenkins_home/workspace/simple-node-js-react-npm-app directory in the Jenkins container).
Save your edited
Jenkinsfile
and commit it to your localsimple-node-js-react-npm-app
Git repository. E.g. Within thesimple-node-js-react-npm-app
directory, run the commands:git add .
thengit commit -m "Add initial Jenkinsfile"
Go back to Jenkins again, log in again if necessary and click Open Blue Ocean on the left to access Jenkins’s Blue Ocean interface.
In the This job has not been run message box, click Run, then quickly click the OPEN link which appears briefly at the lower-right to see Jenkins building your Pipeline project. If you weren’t able to click the OPEN link, click the row on the main Blue Ocean interface to access this feature. Note: You may need to wait several minutes for this first run to complete. After making a clone of your local
simple-node-js-react-npm-app
Git repository itself, Jenkins:Initially queues the project to be run on the agent.
Downloads the Node Docker image and runs it in a container on Docker.
Runs the
Build
stage (defined in theJenkinsfile
) on the Node container. During this time,npm
downloads many dependencies necessary to run your Node.js and React application, which will ultimately be stored in thenode_modules
workspace directory (within the Jenkins home directory).
The Blue Ocean interface turns green if Jenkins built your Node.js and React application successfully.
Click the X at the top-right to return to the main Blue Ocean interface.
Add a test stage to your Pipeline
Go back to your text editor/IDE and ensure your
Jenkinsfile
is open.Copy and paste the following Declarative Pipeline syntax immediately under the
agent
section of yourJenkinsfile
:as well as the following immediately under the
Build
stage:so that you end up with:
The
environment
directive sets the environment variableCI
with a boolean value oftrue
, which is available to all steps in this Pipeline. When thenpm test
command intest.sh
(which is run during theTest
stage defined further down the Pipeline) detects the environment variableCI
with a value oftrue
, then this command is run in "non-watch" (i.e. non-interactive) mode. In "watch" mode,npm test
expects user input, which can pause running builds of CI/CD applications indefinitely. As an alternative to specifying theenvironment
directive in a Jenkins Pipeline, you could also specify this environment variable in thepackage.json
file (to pass on to thenpm test
command) by:Uncommenting the
npm install --save-dev cross-env
command injenkins/scripts/test.sh
(to install thecross-env
dependency during theTest
stage). Read more about this in thetest.sh
file itself.Updating the following line in the
package.json
file (at the root of thesimple-node-js-react-npm-app
repository) from:"test": "react-scripts test --env=jsdom",
to"test": "cross-env CI=true react-scripts test --env=jsdom",
Defines a
stage
(directive) calledTest
that appears on the Jenkins UI.This
sh
step (of thesteps
section) runs the shell scripttest.sh
located in thejenkins/scripts
directory from the root of thesimple-node-js-react-npm-app
repository. Explanations about what this script does are covered in thetest.sh
file itself. As a general principle, it’s a good idea to keep your Pipeline code (i.e. theJenkinsfile
) as tidy as possible and place more complex build scripting steps into separate shell script files like thetest.sh
file. This ultimately facilitates the maintenance of your Pipeline, especially if it gains more complexity.Save your edited
Jenkinsfile
and commit it to your localsimple-node-js-react-npm-app
Git repository. E.g. Within thesimple-node-js-react-npm-app
directory, run the commands:git stage .
thengit commit -m "Add 'Test' stage"
Go back to Jenkins again, log in again if necessary and ensure you’ve accessed Jenkins’s Blue Ocean interface.
Click Run at the top left, then quickly click the OPEN link which appears briefly at the lower-right to see Jenkins running your amended Pipeline project. If you weren’t able to click the OPEN link, click the top row on the Blue Ocean interface to access this feature. Note: You’ll notice from this run that Jenkins no longer needs to download the Node Docker image. Instead, Jenkins only needs to run a new container from the Node image downloaded previously. Also, from now on, no (new)
npm
dependencies should need to be downloaded during the "Build" stage. Therefore, running your Pipeline this subsequent time should be much faster. If your amended Pipeline ran successfully, here’s what the Blue Ocean interface should look like. Notice the additional "Test" stage. You can click on the previous "Build" stage circle to access the output from that stage.Click the X at the top-right to return to the main Blue Ocean interface.
Add a final deliver stage to your Pipeline
Go back to your text editor/IDE and ensure your
Jenkinsfile
is open.Copy and paste the following Declarative Pipeline syntax immediately under the
Test
stage of yourJenkinsfile
:so that you end up with:
This
environment
directive might not be present in your Pipeline if you chose to specify theCI
environment variable in thepackage.json
file above.Defines a new stage called
Deliver
that appears on the Jenkins UI.This
input
step (provided by the Pipeline: Input Step plugin) pauses the running build and prompts the user (with a custom message) to proceed or abort.This
sh
step runs the shell scriptkill.sh
, also located in thejenkins/scripts
directory. Explanations about what this script does are covered in thekill.sh
file itself.Save your edited
Jenkinsfile
and commit it to your localsimple-node-js-react-npm-app
Git repository. E.g. Within thesimple-node-js-react-npm-app
directory, run the commands:git stage .
thengit commit -m "Add 'Deliver' stage"
Go back to Jenkins again, log in again if necessary and ensure you’ve accessed Jenkins’s Blue Ocean interface.
Click Run at the top left, then quickly click the OPEN link which appears briefly at the lower-right to see Jenkins running your amended Pipeline project. If you weren’t able to click the OPEN link, click the top row on the Blue Ocean interface to access this feature. If your amended Pipeline ran successfully, here’s what the Blue Ocean interface should look like. Notice the additional "Deliver" stage. Click on the previous "Test" and "Build" stage circles to access the outputs from those stages.
Ensure you are viewing the "Deliver" stage (click it if necessary), then click the green
./jenkins/scripts/deliver.sh
step to expand its content and scroll down until you see thehttp://localhost:3000
link.Click the
http://localhost:3000
link to view your Node.js and React application running (in development mode) in a new web browser tab. You should see a page/site with the title Welcome to React on it. Tip: If you’re feeling a little adventurous, you can try accessing the terminal/command prompt of your Jenkins Docker container, then using vi editor, tweak and save theApp.js
source file and see the results appear on the Welcome to React page. To do this, run the following commands:This command provides access to the terminal/command prompt of your Jenkins Docker container. The
<docker-container-name>
can be obtained using the commanddocker ps
. Otherwise, it would bejenkins-tutorials
(if you specified this in the command you used to run this container above - i.e.--name jenkins-tutorials
).Once in the container, change directory to the Node.js and React source directory (in the Jenkins workspace directory within Jenkins home).
Access, edit and save changes to your application’s
App.js
file using vi editor.When you are finished viewing the page/site, click the Proceed button to complete the Pipeline’s execution.
Click the X at the top-right to return to the main Blue Ocean interface, which lists your previous Pipeline runs in reverse chronological order.
Wrapping up
Well done! You’ve just used Jenkins to build a simple Node.js and React application with npm
The "Build", "Test" and "Deliver" stages you created above are the basis for building more complex Node.js and React applications in Jenkins, as well as Node.js and React applications that integrate with other technology stacks.
Because Jenkins is extremely extensible, it can be modified and configured to handle practically any aspect of build orchestration and automation.
Last updated