Skip to main content
This lesson shows how to run scripted Jenkins pipeline stages inside Kubernetes pods using the Jenkins Kubernetes plugin. Unlike declarative pipelines where an agent block often handles checkout and workspace for you, scripted pipelines require more explicit control: define pod templates, manage checkouts on each node, and transfer artifacts between agents with stash/unstash. You will learn:
  • How to define a Kubernetes pod via podTemplate and containerTemplate.
  • How to run some stages on a static Jenkins agent and other stages inside Kubernetes containers.
  • How to move installed dependencies (for example node_modules) between agents using stash/unstash.

Inline podTemplate example

Below is a pod template you can generate from Jenkins “Pipeline Syntax” and then simplify for use inside a Jenkinsfile. This example defines a pod with two Node.js container templates:
Explanation:
  • cloud selects the Kubernetes cloud configured in Jenkins.
  • label is the pod label that binds a Jenkins node(...) to this pod template.
  • Each containerTemplate becomes a container inside the created pod. Using sleep keeps the container alive while the Jenkins agent communicates with it.
You can also configure these pod templates at the cloud level in the Jenkins UI so they are reusable across pipelines:
A screenshot of the Jenkins web UI on the "Clouds" page showing one configured cloud named "dasher-prod-k8s-us-east" and a "+ New cloud" button. The page header and navigation are visible across the top.

Use the “Pipeline Syntax” generator

To produce the initial Groovy block, use Jenkins’ “Pipeline Syntax” generator. The form looks like this when creating a pod template for a cloud:
A dark-themed Jenkins Pipeline Syntax page showing a podTemplate configuration form with fields like "Cloud to use" (set to dasher-prod-k8s-us-east), Name, Namespace, Label (nodejs-pod), and usage/inheritance options. The browser window and several tabs are visible along the top.
When adding container templates in the UI, make sure to set fields such as image, command, args, and allocate a TTY if required:
A dark-themed screenshot of a Jenkins Pipeline Syntax / k8s cloud agent configuration page showing container settings. It shows fields like Docker image "node:18-alpine", command "sleep" with argument "9999999", and the "Allocate pseudo-TTY" checkbox checked.
The generator often emits a verbose, YAML-like Groovy snippet including probes and resource defaults. Trim it to the essentials: cloud, label, and containers with name, image, command, args, tty, and privileged flags as needed. For example:
Other pod-level settings (namespace, service account, volumes, workspace directory) can be configured at the cloud level or overridden inline:
A dark-themed screenshot of a web UI (Jenkins Pipeline Syntax / k8s cloud agent settings) showing various form fields. Visible fields include Supplemental Groups, time to retain agent when idle, Pod deadline, Service Account, Node Selector, Working directory (/home/jenkins/agent) and Workspace Volume.

Practical scripted Jenkinsfile pattern

This common pattern uses:
  • A static Jenkins agent (e.g., long-lived Ubuntu/Docker executor) to perform checkout and install dependencies (fast, cache-friendly).
  • stash on that agent to capture installed dependencies.
  • A Kubernetes pod/container to run unit tests after unstashing the artifacts and checkout scm on that node.
Full example Jenkinsfile (scripted pipeline):
  • In scripted pipelines, switching to a different agent/node (for example from a static agent to a Kubernetes pod via node('label')) does not carry over the workspace or checked-out files. Always run checkout scm on the node where you will execute build/test commands, or use stash/unstash to transfer files between agents.
  • stash the produced artifacts on the producer agent (where you installed dependencies) and unstash them on the consumer agent (the Kubernetes container) to make tools and dependencies available where they are needed.

Common failure examples (and fixes)

  1. Missing repository files on the Kubernetes container (ENOENT: package.json).
    Cause: forgetting to checkout scm inside the k8s node(...) block. Failing log example:
Fix: run checkout scm on the same node/container where you invoke npm test.
  1. Missing dev/test tools (e.g., mocha: not found).
    Cause: dependencies were installed on a different agent and not transferred. Symptom: sh: mocha: not found.
    Fix: stash node_modules on the installing agent and unstash on the test agent, or install dependencies inside the test container.
Be mindful of stash size and limits: stashing large directories (e.g., entire build artifacts) may increase build time and storage use. Prefer caching plugins or artifact repositories for large dependencies. Also ensure workspace paths and ownership are compatible across agents (uid/gid differences can affect file access).
After adding checkout scm and unstash to the unit testing stage, the pipeline should successfully provision pods and run tests. Monitor pod provisioning, logs, and step output in the Jenkins UI (Blue Ocean or classic UI):
A Jenkins web dashboard showing the "Gitea-Organization / solar-system" pipeline activity with a table of recent builds (status, run number, commit, branch, message, duration, and completion time). The list shows green, red, and in-progress builds for branches like pipeline/scripted and feature/advanced-demo.
When the pod is provisioned, Jenkins prints the generated Pod YAML and container details in the agent logs. Example snippet you may see in the console output:

Quick reference table

Summary

  • Use podTemplate and containerTemplate to define Kubernetes pods and containers for scripted pipelines.
  • Reference the pod via node('label') and execute inside a container with container('name').
  • Always checkout scm or use stash/unstash when switching between different agents or pods.
  • Define pod templates either inline in the Jenkinsfile (good for one-off pipelines) or in the Jenkins UI/cloud level (recommended for reuse).

Watch Video