Jenkins - ILLYAKO/mywiki GitHub Wiki
Master Server -Controls Pipelines -Schedules Builds Agents/Minions -Perform the Build
Workflow:
- Commit Triggers Pipeline
- Agent Selected based on Configured Labels
- Agent Runs Build
Agent Types:
- Permanent Agents: Dedicated Servers for Running jobs
- Cloud Agents: Ephemeral/Dynamic Agents spun up on demand (Docker, Kubernetes)
Build Types:
- Freestyle Build
- Simplest method to create a build
- "Feels" like Shell Scripting
- Pipelines
- Use theGroovy Syntax
- Use Stages to break down Components of builds (clone, build, test, package, deploy)
git clone https://github.com/git_user_name/your_repo
cd your_repo
Blue Ocean allows users to graphically create, visualize and diagnose CI/CD Pipelines
FROM jenkins/jenkins:2.332.3-jdk11
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean:1.25.3 docker-workflow:1.28"
docker build -t myjenkins-blueocean:2.332.3-1 .
docker network create jenkins
`docker network ls'
docker run --name jenkins-blueocean --restart=on-failure --detach \
--network jenkins --env DOCKER_HOST=tcp://docker:2376 \
--env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 \
--publish 8080:8080 --publish 50000:50000 \
--volume jenkins-data:/var/jenkins_home \
--volume jenkins-docker-certs:/certs/client:ro \
myjenkins-blueocean:2.332.3-1
docker run --name jenkins-blueocean --restart=on-failure --detach `
--network jenkins --env DOCKER_HOST=tcp://docker:2376 `
--env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 `
--volume jenkins-data:/var/jenkins_home `
--volume jenkins-docker-certs:/certs/client:ro `
--publish 8080:8080 --publish 50000:50000 myjenkins-blueocean:2.332.3-1
docker ps
docker exec jenkins-blueocean cat /var/jenkins_home/secrets/initialAdminPassword
and put in the password field in localhost:8080
https://localhost:8080/
Illya 1234 Illya K [email protected] Jenkins URL http://localhost:8080/ Save and Finish
Freestyle project
name my_first_job
Dashboard->my_first_job->Configure->General->Build->Add build step->Execute shell
echo "Hello world!!!"
->Save ->Build Now
Output:
- echo Hello world!!! // command
Hello world!!! // result
Dashboard->my_first_job->Configure->General->Build->See the list of available environment variables
echo "The build ID of this job is ${BUILD_ID}"
echo "The built URL is ${BUILD_URL}"
->Save ->Build Now
Dashboard->my_first_job->Configure->General->Build->Add build step->Execute shell
ls -ltr
echo "1234" > test.txt
ls -ltr
->Save ->Build Now
There is a file in Dashboard->my_first_job->Workspace
Dashboard->my_first_job->Configure->Build Triggers-> Build Environment-> Delete workspace before build starts
->Save ->Build Now
Terminal WSL->Ubuntu
docker exec -it jenkins-blueocean bash
pwd
cd /var/jenkins_home
ls -ltra
cd workspace/my_first_job
Freestyle project
name my_python_job
Dashboard->my_python_job->Configure->Source Code Management->Git->Repository URL
https://github.com/ILLYAKO/jenkins-journey.git
if the repository is private the credentials should be added
Dashboard->my_first_job->Configure->General->Build->Add build step->Execute shell
python3 helloworld.py
->Save ->Build Now
Output:
- python3 helloworld.py // command
Hello world // result
Dashboard->Manage Jenkins->Manage Nodes and Clouds-> Configure Cloud-> Go to plugin manager->Install Docker(Cloud Providers)->Download now and install after restart->Restart Jenkins checkbox-> wait for restart->
Dashboard->Manage Jenkins->Go to plugin manager->Installed->4 installed docker plugins ->
Run Docker Desktop
Dashboard->Manage Nodes and Clouds-> Configure Cloud-> Add a new cloud-> Docker->Docker Cloud Details->S
New node configure the permanent agent to Jenkins(deprecated way)
Installation Reference: https://www.jenkins.io/doc/book/installing/docker/
alpine/socat container to forward traffic from Jenkins to Docker Desktop on Host Machine
https://stackoverflow.com/questions/47709208/how-to-find-docker-host-uri-to-be-used-in-jenkins-docker-plugin
docker run -d --restart=always -p 127.0.0.1:2376:2375 --network jenkins -v /var/run/docker.sock:/var/run/docker.sock alpine/socat tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock
docker ps
docker inspect <container_id> | grep IPAddress
// Docker Host URI
tcp://172.21.0.2:2375
Dashboard->Manage Jenkins->Manage Nodes and Clouds->Configure Clouds->Docker Agent Templates
Labels: docker-agent-alpine // which agent should run the build
Enabled
Name: docker-agent-alpine // is the same as a Label
Docker image: jenkins/agent:alpine-jdk11 // from docker hub or private repository in Registry Authentication...
Container settings... is default
Instance Capacity: 2 // maximum number of container
Remote File System Root: /home/jenkins // Jenkins working directory
...
Save
Dashboard->my_first_job->Configure->General->Restrict where this project can be run->Label Expression->docker-agent-alpine Save-> Build Now
Dashboard->Manage Jenkins->Manage Nodes and Clouds->Configure Clouds->Docker Agent Templates-> Add Docker Template
Labels: docker-agent-python
Enabled
Name: docker-agent-python
Docker image: devopsjourney1/myjenkinsagents:python
Container settings... is default
Instance Capacity: 2
Remote File System Root: /home/jenkins
...
Save
Docker image: devopsjourney1/myjenkinsagents:python
FROM jenkins/agent:alpine-jdk11
USER root
RUN apk add python3
RUN apk add py3-pip
USER jenkins
Dashboard->my_python_job->Configure->General->Restrict where this project can be run->Label Expression->docker-agent-python Save-> Build Now
Jenkins will monitor the git repository
Dashboard->my_python_job->Configure->Source Code Management->Build Triggers->Poll SCM
*/5****
// every 5 minute
Save
Dashboard->New Item->my_first_build_pipeline->Pipeline->Ok->Pipeline->Definition-> Pipeline Script
Declarative Pipeline is a relatively recent addition to Jenkins Pipeline which presents a more simplified and opinionated syntax on top of the Pipeline sub-systems.
pipeline {
agent {
node {
label 'jenkins-agent-goes-here'
}
}
stages {
stage('Build') {
steps {
echo "Building.."
sh '''
echo "doing build stuff.."
'''
}
}
stage('Test') {
steps {
echo "Testing.."
sh '''
echo "doing test stuff..."
'''
}
}
stage('Deliver') {
steps {
echo "Deliver...."
sh '''
echo "doing delivery stuff.."
'''
}
}
}
}
Save -> Build Now
Create Jenkinsfile in Visual Studio Code
pipeline {
agent {
node {
label 'docker-agent-python'
}
}
triggers {
pollSCM '*/5 * * * *'
}
stages {
stage('Build') {
steps {
echo "Building.."
sh '''
cd myapp
pip install -r requirements.txt
'''
}
}
stage('Test') {
steps {
echo "Testing.."
sh '''
cd myapp
python3 hello.py
python3 hello.py --name=Illya
'''
}
}
stage('Deliver') {
steps {
echo 'Deliver....'
sh '''
echo "doing delivery stuff.."
'''
}
}
}
}
Dashboard->my_first_build_pipeline->Configure->Pipeline-Pipeline script from SCM->SCM->Git->Repository->Repository URL->https://github.com/ILLYAKO/jenkins-journey.git->Script Path->Jenkinsfile-> Save
https://www.youtube.com/watch?v=pMO26j2OUME&list=PLy7NrYWoggjw_LIiDK1LXdNN82uYuuuiC
jenkins-docker-app
- Jenkins Container Setup
- Create Multibranch Pipeline with Git Repo
- Types of Credentials
- Jenkinsfile
Code -> Commit-> Git Repo-> Trigger build -> Jenkinsfile:test, build, deploy
Run Jenkins in Docker Container
1.1. Find a Jenkins image in dockerhub
The image 'jenkins/jenkins' should be used.
- Expose port 8080 -- By default runs on that port
- Expose port 50000 -- Master/Slaver Communication
- Run in detached mode -- run container in the background
- Bind named volume -- persist data of Jenkins, bind host directory and container directory
- image version -- latest (jenkins/jenkins:lts)
.
docker run --name jenkins -p 8080:8080 -p 50000:50000 -d -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts
docker ps
docker logs your_ContainerID
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
3adc1a26a8fd4128a816ca8ba01da498
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
IlLya 1234 Illya K [email protected] Jenkins URL http://localhost:8080/ Save and Finish
- Freestyle: simple, single tasks e.g. run tests
- Pipeline: whole delivery cycle e.g. test|build|... for a single branch
- Multibranch Pipeline : like pipeline for multiple branches
Updates
Available plugins
Installed plugins
Advanced settings
Download progress
Name: "my-pipeline"
Branch Source = Project you want to build
Add Source -> Git
Project Repository - Specify the URL of this remote repository. This uses the same syntax as your git clone command HTTPS.
https://github.com/ILLYAKO/jenkins-docker-app.git
Credentials - > choose created credentials for git repo.
Behaviours -> Add ->
Behaviors: Discover branches
Filter by name (with regular expression) -> .* (default means all branches)
Build Configuration
Mode -> by Jenkins(default)
Script Path -> Jenkinsfile(default)
Save
"Credentials" Plugin to store and manage them centrally
Dashboards -> Manage Jenkins -> Manage Credentials -> Credentials -> Jenkins System(Store) -> global(Domains) -> Add Credentials
Kinds:
-Username with password
-GitHub App
-SSH Username with private key
-Secret file
-Secret text
-Certificate
Credential Scopes:
-System: Only available on Jenkins server NOT for Jenkins jobs
-Global: Everywhere accessible
-Project: Limited to project, ONLY with multibranch pipeline (on project page)
ID = Reference for your credentials
Kind: User with password
Scope: Global (Jenkins, nodes, items, all child items, etc)
Username: global
Password: 1234
ID: global
Kind: User with password
Scope: System (Jenkins and nodes only)
Username: system
Password: 1234
ID: system
kind: username with password
Username: [email protected]
password: *******
ID: demo-app-git-credentials
Go Dashboard -> my-pipeline -> Configuration -> Branch Sources -> Behaviours -> Add
Behaviors: Discover branches
Filter by name(with regular expression):^dev|master|feature.*$
- Scripted
-first syntax
-Groovy engine
-Advanced scripting capabilities, high flexibility
-difficult to start
- Declarative -recent addition -easier to get started, but not that powerful -pre-defined structure
-'pipeline' must be top-level -'agent' -where to execute -'stages' -where the 'work' happens -'stage' and 'steps' -'step' -where execute a command in the Jenkins server
pipeline {
agent any
stages {
stage("build") {
steps {
echo 'building the application...'
}
}
stage("test") {
steps {
echo 'testing the application...'
}
}
stage("deploy") {
steps {
echo 'deploying the application...'
}
}
}
}
Dashboard -> my-pipeline -> Scan Multibranch Pipeline Now
Dashboard -> my-pipeline -> Scan Multibranch Pipeline Log
Project configuration must be done in the project pipeline or Jenkinsfile (NOT in the branch)
Dashboard->my-pieline->branch->Build History(choose last)-> Replay -> Main Script-> Change -> Run
...
steps {
echo 'building the application...'
script{
def test = 2+2 > 3 ? 'cool' : 'not good'
echo test
}
}
...
Dashboard->my-pieline->branch->Build History(choose dropdown menu) -> Restart from Stage -> Chose Stage -> Run
Git Integration
-Push Notification
-Polling for Changes
commit -> Git Repo -> trigger build
2 ways to trigger a build
-Push Notification: Version Control notifies Jenkins on a new commit(more efficient)
-Polling: Jenkins polls in regular intervals
Trigger build:
-Install the Jenkins plugin based on your Version Control System
-Configure Repository Server Hostname
-Access Token and Credential in Dashboard->Manage Jenkins->Configure System->GitHub->Add GitHub Server
Developer->commits->Git Repo->pushes to->Jenkins Webhook url->Jenkins lets me trigger that build for you
Dashboard->my-pipeline->Configuration->Scan Multibranch Pipeline Triggers->Interval(1 hour)->Save Goof strategy to configure both as a backup plan
Scripted pipeline. Pipeline as a code -scripted pipeline -is created in your repository
Pipeline Syntax
- Scripted
-first syntax
-Groovy engine
-Advanced scripting capabilities, high flexibility
-difficult to start
- Declarative -recent addition -easier to get started, but not that powerful -pre-defined structure
-'pipeline' must be top-level -'agent' -where to execute -'stages' -where the 'work' happens -'stage' and 'steps' -'step' -where execute a command in the Jenkins server
pipeline {
agent any
stages {
stage("build") {
steps {
echo 'building the application...'
}
}
stage("test") {
steps {
echo 'testing the application...'
}
}
stage("deploy") {
steps {
echo 'deploying the application...'
}
}
}
}
Execute some logic AFTER all stages executed Conditions:
-always -success -failure Build Status or Build Status Changes
pipeline {
agent any
stages {
...
}
post {
always{}
success{}
failure{}
}
}
The "When condition" directs if steps will be executed
...
stage("build") {
when {
expression {
BRANCH_NAME == 'dev' && CODE_CHANGE == true
}
}
steps {
echo 'testing the application...'
}
}
stage("test") {
when {
expression {
BRANCH_NAME == 'dev' || BRANCH_NAME == 'master'
}
}
steps {
echo 'testing the application...'
}
}
...
Jenkins variable located here http://localhost:8080/env-vars.html/ Double quotes must use.
pipeline {
agent any
environment {
NEW_VERSION = '1.3.0'
}
stages {
stage("build") {
steps {
echo "building the application version ${NEW_VERSION}"
}
...
- Define Credentials in Jenkins GUI (Global Domain)
- "credentials("credentialId")" binds the credentials to your env variable
- For that you need a "Credentials Binding" Plugin
pipeline {
agent any
environment {
NEW_VERSION = '1.3.0'
SERVER_CREDENTIAS = credentials('server-credentials') // credentialID from Jenkins server
}
....
...
stage("deploy") {
steps {
echo 'deploying the application...'
withCredentials([
usernamePassord(credentials: 'server-credentials', usernameVariable: USER, passwordVariable: PWD)
]){
sh "some script ${USER} ${PWD}"
}
}
}
...
-Credentials -Credentials Binding
Access build tools for your projects
Only 3 build tools are available: gradle, maven, jdk
the tool should be preinstalled in the Jenkins server Dashboard -> Manage Jankins -> Global Tool Configuration
pipeline {
agent any
tools{
maven 'Maven'
}
...
Types of Parameter:
-string (name, defaultValue, description)
-choice (name, choices, description)
-booleanParam (name, defaultValue, description)
pipeline {
agent any
parameters {
string(name: 'VERSION', defaultValue: '', description: 'version to deploy on prod')
choice(name: 'VERSION', choices: ['1.1.0', '1.2.0', '1.3.0'])
booleanParam(name: 'executeTests', defaultValue: true)
}
...
when {
expression {
params.executeTests == true
}
}
...
If there is an empty parameter or choice, go to "Build with Parameters"
Jenkins Dashboard -> my-pipeline -> master-> Build with Parameters
All environmental variables in Jenkinsfile are available in the groovy script
def buildApp() {
echo 'building the application from grovy script'
}
def testApp() {
echo 'testing the application from grovy script'
}
def deployApp() {
echo 'deploying the application from grovy script'
}
return this
def gv
pipeline {
agent any
parameters {
string(name: 'VERSION', defaultValue: '', description: 'version to deploy on prod')
choice(name: 'VERSION1', choices: ['1.1.0', '1.2.0', '1.3.0'])
booleanParam(name: 'executeTests', defaultValue: true)
}
environment {
NEW_VERSION = '1.3.0'
SERVER_CREDENTIAS = credentials('server-credentials') // credentialID from jendins server
}
stages {
stage("init") {
steps {
script {
gv = load "script.groovy"
}
}
}
stage("build") {
when {
expression {
BRANCH_NAME == 'dev' && CODE_CHANGE == true
}
}
steps {
echo "building the application version ${NEW_VERSION}"
script {
gv.buildApp()
}
}
}
Dashboard->my-pieline->branch->Build History(choose last)-> Replay -> Main Script-> Change -> Run