Hi I am new to Devops and I am trying to create a simple Jenkins Pipleine. In which I need to push the docker image to dockerhub. Entire pipeline including Jenkins is hosted on Kubernetes.
Below is the Jenkinsfile. I am giving the credentials inline which is bad. I have stored my dockerhub password in Jenkins as a secret text, but not sure how to reference it here.
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: docker
image: docker:latest
command:
- cat
tty: true
volumeMounts:
- mountPath: /var/run/docker.sock
name: docker-sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
'''
}
}
stages {
stage('Clone') {
steps {
container('docker') {
git branch: 'main', changelog: false, poll: false, url: '<my github URL>'
}
}
}
stage('Build-Docker-Image') {
steps {
container('docker') {
sh 'docker build -t <my-dockerhub-username>/testing-image:latest .'
}
}
}
stage('Login-Into-Docker') {
steps {
container('docker') {
sh 'docker login -u <my-dockerhub-username> -p <my-dockerhub-password>'
}
}
}
stage('Push-Images-Docker-to-DockerHub') {
steps {
container('docker') {
sh 'docker push <my-dockerhub-username>/testing-image:latest'
}
}
}
stage('Remove docker Images') {
steps {
container('docker') {
sh 'docker image prune -af'
}
}
}
}
post {
always {
container('docker') {
sh 'docker logout'
}
}
}
}
I tried
stage('Push-Images-Docker-to-DockerHub') {
steps {
withCredentials([string(credentialsId: 'Docker_PW', variable: 'Docker_PW')])
container('docker') {
sh 'docker push <my-dockerhub-username>/testing-image:latest'
}
}
}
But my pipeline fails after coming to this step. Please assist if possible.
Do it this way:
environment {
DOCKERHUB_CREDENTIALS=credentials('dockerhub')
}
stages {
stage('gitclone') {
...
}
stage('Login') {
steps {
sh 'echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin'
}
}
stage('Push') {
...
}
}
Refers to: https://github.com/shazforiot/How-to-Push-docker-image-to-Docker-Hub-using-Jenkins-Pipeline/blob/main/Jenkinsfile
Related
Hi I have set up a pipeline that pulls from Github when there's a commit and publishes an image to Dockerhub. My Pipeline script is as follows:
pipeline {
environment {
registry = "momo979/purple-beard-team-2"
registryCredential = 'dockerhub'
dockerImage= ''
}
agent any
stages {
stage('Cloning Git') {
steps {
git 'https://github.com/Momo979/JenkinsTest.git'
}
}
stage('Building image') {
steps{
script {
docker.build registry + ":$BUILD_NUMBER"
}
}
}
stage('Deploy Image') {
steps{
script {
docker.withRegistry( '', registryCredential ) {
dockerImage.push()
}
}
}
}
stage('Remove Unused docker image') {
steps{
sh "docker rmi $registry:$BUILD_NUMBER"
}
}
}
}
The image gets built ok but during the deploy phase I am getting the following message which causes everything to fail.
"groovy.lang.MissingPropertyException: No such property:
dockerImage for class: groovy.lang.Binding at
groovy.lang.Binding.getVariable(Binding.java:63)"
I have this configuration in my pipeline job
def k8sTestPodTemplate(docker_image) {
return """
apiVersion: v1
kind: Pod
metadata:
name: my-agent
labels:
name: my-agent
spec:
serviceAccountName: jenkins
containers:
- name: python
image: ${docker_image}
command: ["/bin/bash", "-c", "cat"]
tty: true
"""
}
pipeline {
agent none
stages {
stage('Run tests') {
parallel {
stage('Tests Python 3.5') {
agent {
kubernetes {
defaultContainer 'jnlp'
yaml k8sTestPodTemplate('python:3.5')
}
}
steps {
container('python') {
sh "echo 'Hello from Python 3.5'"
}
}
}
stage('Tests Python 3.6') {
agent {
kubernetes {
defaultContainer 'jnlp'
yaml k8sTestPodTemplate('python:3.6')
}
}
steps {
container('python') {
sh "echo 'Hello from Python 3.6'"
}
}
}
stage('Tests Python 3.7') {
agent {
kubernetes {
defaultContainer 'jnlp'
yaml k8sTestPodTemplate('python:3.7')
}
}
steps {
container('python') {
sh "echo 'Hello from Python 3.7'"
}
}
}
}
}
}
}
But as you can see I could easily improve this code to something like that:
def k8sTestPodTemplate(docker_image) {
return """
apiVersion: v1
kind: Pod
metadata:
name: my-agent
labels:
name: my-agent
spec:
serviceAccountName: jenkins
containers:
- name: python
image: ${docker_image}
command: ["/bin/bash", "-c", "cat"]
tty: true
"""
}
def generateStage(docker_image) {
return {
stage("Tests ${docker_image}") {
agent {
kubernetes {
defaultContainer 'jnlp'
yaml k8sTestPodTemplate("${docker_image}")
}
}
steps {
container('python') {
sh "echo ${docker_image}"
}
}
}
}
}
pipeline {
agent none
stages {
stage('Run tests') {
parallel {
generateStage("python:3.5")
generateStage("python:3.6")
generateStage("python:3.7")
}
}
}
}
But I cannot get this to work. The problem is that Jenkins is raising an error
No such DSL method 'agent' found among steps
I am using the "agent" directive inside the "step" directive and the agent is being generated dynamically.
I configed a jenkins pipeline to build a project that get from github. But I got an error at step 2 - Build image. Then, I tried to add user admin (of jenkins) to group "docker", and I can run build command successfully without error when login by user admin in the kubernetes master vm, however still error with jenkins. I used blueocean plugin for creating the pipeline. Do you know how to fix this ?
UPDATE: Please see my jenkinsfile
pipeline {
environment {
registry = "192.168.64.162:5000/justme/myweb"
dockerImage = ""
}
agent any
stages {
stage('Checkout Source') {
steps {
git 'https://github.com/taibc/playjenkins.git'
}
}
stage('Build image') {
steps{
script {
dockerImage = docker.build registry + ":$BUILD_NUMBER"
}
}
}
stage('Push Image') {
steps{
script {
docker.withRegistry( "" ) {
dockerImage.push()
}
}
}
}
stage('Deploy App') {
steps {
script {
kubernetesDeploy(configs: "myweb.yaml", kubeconfigId: "mykubeconfig")
}
}
}
}
}
I resolve this problem by installing Jenkins to another server (not belong to kubernetes cluster). But, I got another problem when deploying app as the link: https://github.com/jenkinsci/kubernetes-cd-plugin/issues/122
Here my yaml file
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: myweb
name: myweb
spec:
replicas: 1
selector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- image: 192.168.94.162:5000/justme/myweb:1
imagePullPolicy: Always
name: myweb
---
apiVersion: v1
kind: Service
metadata:
labels:
app: myweb
name: myweb
spec:
ports:
- nodePort: 32223
port: 80
protocol: TCP
targetPort: 80
selector:
app: myweb
type: NodePort
Here my jenkinsscript
pipeline {
environment {
registry = "192.168.94.162:5000/justme/myweb"
dockerImage = ""
}
agent any
stages {
stage('Checkout Source') {
steps {
git 'https://github.com/taibc/playjenkins.git'
}
}
stage('Build image') {
steps{
script {
dockerImage = docker.build registry + ":$BUILD_NUMBER"
}
}
}
stage('Push Image') {
steps{
script {
docker.withRegistry( "" ) {
dockerImage.push()
}
}
}
}
stage('Deploy App') {
steps {
script {
kubernetesDeploy(configs: "myweb.yaml", kubeconfigId: "mykubeconfig")
}
}
}
}
}
I'm new with Jenkins, and I would like to get almost the same behavior as in GitLab CI for one of my PHP project.
I use Docker to test my project on several PHP versions.
What I want ?
Running build and test in parallel.
Build creates my application, sources come from a git repository, and I run the composer install command.
Dockerfile is stored in /var/lib/jenkins/Docker
My Dockerfile has a parameter (PHP_VERSION) which allow me to choose the PHP version I want
customWorkspace seems to work
Here is my Jenkinsfile to do so :
updateGitlabCommitStatus name: 'build', state: 'pending'
pipeline {
agent none
post {
failure {
updateGitlabCommitStatus name: 'build', state: 'failed'
}
success {
updateGitlabCommitStatus name: 'build', state: 'success'
}
}
stages {
stage('build') {
parallel {
stage('build-php5.4') {
agent {
dockerfile {
additionalBuildArgs '--build-arg PHP_VERSION=54'
dir '/var/lib/jenkins/Docker'
customWorkspace './build-php5.4'
}
}
steps {
sh 'pwd'
sh 'ls'
sh 'rm -Rf composer.lock vendor'
sh 'composer install'
}
}
stage('build-php7.0') {
agent {
dockerfile {
additionalBuildArgs '--build-arg PHP_VERSION=70'
dir '/var/lib/jenkins/Docker'
customWorkspace './build-php7.0'
}
}
steps {
sh 'pwd'
sh 'rm -Rf composer.lock vendor'
sh 'composer install'
}
}
}
}
stage('tests') {
parallel {
stage('test-php5.4') {
agent {
dockerfile {
additionalBuildArgs '--build-arg PHP_VERSION=54'
dir '/var/lib/jenkins/Docker'
customWorkspace './build-php5.4'
}
}
steps {
sh 'pwd'
sh 'php --version'
sh 'php vendor/phpunit/phpunit/phpunit tests'
}
}
stage('test-php7.0') {
agent {
dockerfile {
additionalBuildArgs '--build-arg PHP_VERSION=70'
dir '/var/lib/jenkins/Docker'
customWorkspace './build-php7.0'
}
}
steps {
sh 'pwd'
sh 'php --version'
sh 'php vendor/phpunit/phpunit/phpunit tests'
}
}
}
}
}
}
And here is the result :
It looks good, but it isn't, and I don't really understand the underlying behavior.
As you can see, the test-php54 stage uses the last created Docker container :
I'm sure I'm wrong on a lot of steps, but do you think I can do it this way ?
Ok, I found the main problem.
The fact is I use the same Dockerfile, but with different parameters.
If I create one Dockerfile for PHP 5.4 and another one for PHP 7.0, the stages are parallelized correctly.
updateGitlabCommitStatus name: 'build', state: 'pending'
pipeline {
agent none
post {
failure {
updateGitlabCommitStatus name: 'build', state: 'failed'
}
success {
updateGitlabCommitStatus name: 'build', state: 'success'
}
}
stages {
stage('build') {
parallel {
stage('build-php5.4') {
agent {
dockerfile {
dir '/var/lib/jenkins/Docker'
filename 'Dockerfile-php5.4'
customWorkspace './build-php5.4'
}
}
steps {
sh 'rm -Rf composer.lock vendor'
sh 'composer install'
}
}
stage('build-php7.0') {
agent {
dockerfile {
dir '/var/lib/jenkins/Docker'
filename 'Dockerfile-php7.0'
customWorkspace './build-php7.0'
}
}
steps {
sh 'rm -Rf composer.lock vendor'
sh 'composer install'
}
}
}
}
stage('tests') {
parallel {
stage('test-php5.4') {
agent {
dockerfile {
dir '/var/lib/jenkins/Docker'
filename 'Dockerfile-php5.4'
customWorkspace './build-php5.4'
}
}
steps {
sh 'php --version'
sh 'php vendor/phpunit/phpunit/phpunit tests'
}
}
stage('test-php7.0') {
agent {
dockerfile {
dir '/var/lib/jenkins/Docker'
filename 'Dockerfile-php7.0'
customWorkspace './build-php7.0'
}
}
steps {
sh 'php --version'
sh 'php vendor/phpunit/phpunit/phpunit tests'
}
}
}
}
}
}
This seems to work ! :)
I try to use the post steps with the Jenkins kubernetes plugin. Does anyone has an idea?
java.lang.NoSuchMethodError: No such DSL method 'post' found among steps
My pipeline:
podTemplate(
label: 'jenkins-pipeline',
cloud: 'minikube',
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
]) {
node('jenkins-pipeline') {
stage('test') {
container('maven') {
println 'do some testing stuff'
}
}
post {
always {
println "test"
}
}
}
}
As of this writing, Post is only supported in declarative pipelines.
You could have a look at their declarative example if you absolutely must use post.
pipeline {
agent {
kubernetes {
//cloud 'kubernetes'
label 'mypod'
containerTemplate {
name 'maven'
image 'maven:3.3.9-jdk-8-alpine'
ttyEnabled true
command 'cat'
}
}
}
stages {
stage('Run maven') {
steps {
container('maven') {
sh 'mvn -version'
}
}
}
}
}
This example shows how to use the post step using the Kubernetes plugin:
pipeline {
agent {
kubernetes {
label "my-test-pipeline-${BUILD_NUMBER}"
containerTemplate {
name "my-container"
image "alpine:3.15.0"
command "sleep"
args "99d"
}
}
}
stages {
stage('Stage 1') {
steps {
container('my-container') {
sh '''
set -e
echo "Hello world!"
sleep 10
echo "I waited"
echo "forcing a fail"
exit 1
'''
}
}
}
}
post {
unsuccessful {
container('my-container') {
sh '''
set +e
echo "Cleaning up stuff here"
'''
}
}
}
}