4

I am trying to create a Pipeline where Jenkins builds my Docker image, runs tests, and then deploys the container if the tests pass. The problem is that I have maven running inside the docker container, and I can't actually access the published tests until I run the container. I want the Docker container to be ran and deployed after the tests pass. This seems like a simple thing to do, but I can't think of a good way to do it. Am I misunderstanding something? Thanks.

Dockerfile:

FROM openjdk:10 as step-one

COPY ./ /var/www/java/
WORKDIR /var/www/java

RUN apt-get update -y && apt-get install -y maven 

RUN mvn clean package -X

ENTRYPOINT ["java"]
CMD ["-jar",  "target/gs-serving-web-content-0.1.0.jar"]

EXPOSE 8080

Jenkinsfile:


pipeline {

    agent any

        stages {
            stage('Build') {
                steps {
                    echo 'Building..'
                    sh 'docker build -t spring-image .'

                }
            }
            stage('Test') {
                steps {
                    echo 'Testing..'
                    junit '/var/www/java/target/surefire-reports/TEST-ma.SpringTest.xml'                 
                }
            }


            stage('Deploy') {
                steps {
                    echo 'Deploying....'
                        sh 'docker run -i -d --name spring-container spring-image'
                }
            }
        }
}


Logan Phillips
  • 660
  • 2
  • 10
  • 23

2 Answers2

3

You can use fact that docker container home repository is a shared volume with local jenkins workspace.

Simplest pipeline script:

newApp.inside('-e NODE_ENV=test') { sh 'npm install --dev' sh 'gulp test:unit' } junit 'reports/*.xml'

A bit complex example with some collateral work in separate stages (note that maven build image is using .m2 cache as non-root user):

    try {
    buildEnvImg.inside("-v /jenkins/.m2:/var/maven/.m2 -e MAVEN_CONFIG=/var/maven/.m2 -v /jenkins/.cache:/var/maven/.cache -v /var/run/docker.sock:/var/run/docker.sock") {
        stage('Compile') {
            sh 'mvn -Duser.home=/var/maven -B -DskipTests clean compile'
        }
        stage('Build jar') {
            sh 'mvn -Duser.home=/var/maven -B -DskipTests package'
        }
        stage('Build docker') {
            sh 'mvn -Duser.home=/var/maven -B -DskipTests jib:dockerBuild'
        }
        stage('Test') {
            echo 'Going to execute mvn test, thus automated tests contained in project will be compiled and executed.'
            sh 'mvn -Duser.home=/var/maven -B test'
        }
    }
} finally {
    junit 'target/surefire-reports/*.xml'
}

Solution digged out from Jenkins build inside a docker container with generated reports .

Lubo
  • 1,621
  • 14
  • 33
2

You could create an temporary container just before junit to extract test results files to copy test result to your workspsace. And finally remove it

sh 'docker create --name temporary-container spring-image'
sh 'docker cp temporary-container:/var/www/java/target/surefire-reports .'
sh 'docker rm temporary-container'
junit 'surefire-reports'

You could also take a look do docker-pipeline documentations which provides you some abstraction to build docker images

Gonzalo Matheu
  • 8,984
  • 5
  • 35
  • 58
  • Thanks @Gonzalo Matheu. This looks pretty good and makes a lot of sense. I'm going to give this a try and look closer at the link you provided. – Logan Phillips Mar 28 '19 at 19:48
  • You know, sometimes I just want to toss the Pipeline tooling and do it from shell. I get it but if you open a Docker container you can just publish within the pipeline itself. – ingyhere Aug 29 '20 at 03:57
  • Please tell me this is not why I lost the last 4 hours... – Andrei Zisu Nov 29 '22 at 16:10