Setting up continuous integration isn't just a buzzword anymore - it's become the backbone of modern software development. Every code commit triggers automated tests, and only the changes that pass get deployed to production. Think of it as having a vigilant gatekeeper that never sleeps, never gets tired, and catches bugs before they reach your users.
This guide walks you through building a practical continuous delivery pipeline by connecting Jenkins with container orchestration. You'll learn how to automate testing and image building, so your team can ship faster without breaking things.
The traditional approach of manual testing and deployment creates bottlenecks. Developers wait hours or days for feedback, bugs slip through, and deployments become stressful events. Continuous integration flips this model - it validates every change immediately, maintains code quality automatically, and turns deployment into a non-event.
When you combine Jenkins with containerized workflows, you get consistent build environments, reproducible deployments, and the ability to scale your CI/CD infrastructure effortlessly. 👉 Get started with cloud-native container solutions that scale with your team.
Deploying the Master and Worker Nodes
First, you'll create a Jenkins orchestration template. This defines how your Jenkins master and slave nodes communicate and scale.
Create a new template with this configuration:
yaml
jenkins:
image: 'registry.aliyuncs.com/acs-sample/jenkins:latest'
ports:
- '8080:8080'
- '50000:50000'
volumes:
- /var/lib/docker/jenkins:/var/jenkins_home
privileged: true
restart: always
labels:
aliyun.scale: '1'
aliyun.probe.url: 'tcp://container:8080'
aliyun.probe.initial_delay_seconds: '10'
aliyun.routing.port_8080: jenkins
links:
- slave-nodejs
slave-nodejs:
image: 'registry.aliyuncs.com/acs-sample/jenkins-slave-dind-nodejs'
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
aliyun.scale: '1'
This template provisions both the Jenkins master (handling job coordination and UI) and a Node.js slave container (executing actual build tasks). The slave mounts the Docker socket, enabling it to build and push images from within a containerized environment.
Once you deploy this template, both services appear in your container dashboard. Access Jenkins through the provided endpoint and you're ready to configure jobs.
Connecting Slave Nodes to Jenkins
Open Jenkins and navigate to System Settings > Manage Node > Create Node. Configure these parameters:
Node name: Something descriptive like slave-nodejs-ut
Remote root directory: /home/jenkins
Labels: nodejs-test (you'll reference this when creating jobs)
Launch method: Launch agent via Java Web Start
Host: Use the internal container IP address for network isolation
For credentials, use the jenkins account with password jenkins (defined in the slave container's Dockerfile).
Creating the Unit Test Job
Now create a freestyle project in Jenkins:
Name it something clear like "nodejs-unit-tests"
Restrict where this project runs by specifying the label nodejs-test
Under source code management, connect your GitHub repository and specify the branch
Configure automatic triggering through GitHub webhooks. In your GitHub project settings, navigate to Webhooks & services > Add service and select Jenkins (Git plugin). Enter your Jenkins webhook URL:
http://your-jenkins-domain.com/github-webhook/
Now every push to your repository will trigger this Jenkins job automatically.
Add an Execute shell build step with these commands:
bash
pwd
ls
cd chapter2
npm test
This navigates to your code directory and runs your test suite. If tests fail, Jenkins marks the build as failed and stops the pipeline.
Creating the Build Job
Create another freestyle project for building and pushing Docker images. This job should only run after successful unit tests - you don't want broken code turned into deployable artifacts.
Under Build Triggers, select "Build after other projects are built" and specify your unit test job. Choose "Trigger only if build is stable."
The shell script for this job handles three tasks: building the image, authenticating with your registry, and pushing the result.
bash
cd chapter2
docker build -t registry.aliyuncs.com/your-namespace/nodejs-demo .
docker login -u ${yourAccount} -p ${yourPassword} registry.aliyuncs.com
docker push registry.aliyuncs.com/your-namespace/nodejs-demo
Replace yourAccount and yourPassword with your actual registry credentials. For production use, store these as Jenkins credentials rather than hardcoding them.
Managing container infrastructure and orchestration at scale becomes significantly easier when you leverage managed services. 👉 Explore enterprise-grade container orchestration with automated scaling and monitoring.
Initial Application Deployment
Deploy your application using this orchestration template:
yaml
express:
image: 'registry.aliyuncs.com/your-namespace/nodejs-demo'
expose:
- '22'
- '3000'
restart: always
labels:
aliyun.routing.port_3000: express
This creates a service named nodejs-demo that pulls your freshly built image.
Connecting Jenkins to Your Deployment
Create a deployment trigger in your container service console. This generates a webhook URL that redeploys your application when called.
Add this line to your image build shell script:
bash
curl 'https://cs.console.aliyun.com/hook/trigger?triggerUrl=***&secret=***'
Your complete build script now looks like this:
bash
cd chapter2
docker build -t registry.aliyuncs.com/your-namespace/nodejs-demo .
docker login -u ${yourAccount} -p ${yourPassword} registry.aliyuncs.com
docker push registry.aliyuncs.com/your-namespace/nodejs-demo
curl 'https://cs.console.aliyun.com/hook/trigger?triggerUrl=***&secret=***'
Now the flow is complete: code push → automated tests → image build → registry push → production deployment. All without manual intervention.
Getting real-time updates about build status helps teams respond quickly to problems.
Configuring the SMTP Server
Navigate to System Management > System Settings in Jenkins. Set your system administrator email address - this appears as the sender in all notifications.
Install the Extended Email Notification plugin, then configure your SMTP server details:
SMTP server: Your email provider's SMTP address
Default recipients: Comma-separated list of team members
Authentication: Your SMTP username and password
Adding Notifications to Jobs
In each Jenkins project, add a post-build action called Editable Email Notification. Specify recipients who should be notified about this specific job.
Add triggers for different scenarios:
Always: Send on every build
Failure: Only when builds fail
Success: Only when builds succeed after previous failures
This way, developers get immediate feedback when their changes break tests, and the team celebrates when previously broken builds get fixed.
You've now built a complete CI/CD pipeline that:
Automatically tests every code change
Builds Docker images only from validated code
Pushes images to a registry
Redeploys applications with zero downtime
Notifies teams about build status
The beauty of this setup is its reproducibility. Every build happens in an isolated container with identical dependencies. No more "works on my machine" problems.
As your team grows and projects multiply, this containerized Jenkins architecture scales horizontally - just add more slave nodes to handle increased load. The combination of automated testing, containerized builds, and continuous deployment eliminates entire categories of deployment bugs and operational headaches.
Start small with one project, validate the approach, then expand it across your organization. The initial setup investment pays dividends every single day as your team ships features faster and with more confidence.