Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Getting Started With Docker for Java Applications: Setting Up a CI/CD Pipeline

DZone's Guide to

Getting Started With Docker for Java Applications: Setting Up a CI/CD Pipeline

This article is a guide to containerizing an existing Java web application and using Jenkins to set up an end-to-end deployment pipeline.

· DevOps Zone ·
Free Resource

Read why times series is the fastest growing database category.

Docker is already quite famous and more organizations are moving to Docker-based application development and deployment. Here is a quick guide on how to containerize an existing Java web application and set up an end to end deployment pipeline for it using Jenkins.

I am using the very famous Spring based pet store application for this, and it represents a good sample, as most applications follow a similar architecture.

Steps

  1. Build the Petstore application.
  2. Run a Sonar quality check on this.
  3. Prepare the Docker image with the web application.
  4. Run the container and execute integration tests.
  5. If the tests are successful, push the image to a dockerhub account.

All the code is available here.

Here is the Jenkins pipeline code which can be used for the above steps:

Jenkins Pipeline

node {
    stage 'checkout'
    git 'https://gitlab.com/RavisankarCts/hello-world.git' 

    stage 'build'
    sh 'mvn clean install'

    stage('Results - 1') {
         junit '**/target/surefire-reports/TEST-*.xml'
         archive 'target/*.jar'
        }

    stage 'bake image'
    docker.withRegistry('https://registry.hub.docker.com','docker-hub-credentials') {
        def image = docker.build("ravisankar/ravisankardevops:${env.BUILD_TAG}",'.')

        stage 'test image'
        image.withRun('-p 8888:8888') {springboot ->
        sh 'while ! httping -qc1 http://localhost:8888/info; do sleep 1; done'
        git 'https://github.com/RavisankarCts/petclinicacceptance.git'
        sh 'mvn clean verify'
        }

        stage('Results') {
         junit '**/target/surefire-reports/TEST-*.xml'
         archive 'target/*.jar'
        }

        stage 'push image'
        image.push()
    }
}

The initial steps just check out the code and run the build. The interesting part starts with this step, which runs within a Docker context using dockerhub credentials

step 3 'bake image'
docker.withRegistry('https://registry.hub.docker.com','docker-hub-credentials') 

Configuring Docker Hub Credentials

This step builds the Docker image. The Docker build command takes your dockerhub repository name and the tag name as one argument and your build location as another argument.

def image = docker.build("dockerhub registry name":"tag name",'location of docker file'). 
def image = docker.build("ravisankar/ravisankardevops:${env.BUILD_TAG}",'.')

This uses the Dockerfile to build the Docker image. The contents of the Docker file:

FROM tomcat:8

ADD target/*.war /usr/local/tomcat/webapps

The next step is to run the image and run tests on it.

stage 'test image'
        image.withRun('-p 8888:8888') { springboot ->
        sh 'while ! httping -qc1 http://localhost:8888/info; do sleep 1; done'
        git 'https://github.com/RavisankarCts/petclinicacceptance.git'
        sh 'mvn clean verify'
}

The withRun step helps you to run the Docker image you just built and expose the port where this application can be exposed. I have another test code base which is built and executed which will run tests on the image that is running.

The final step is pushing the image to a dockerhub registry or any internal registry setup in your organization.

Image title

stage('Results') {
         junit '**/target/surefire-reports/TEST-*.xml'
         archive 'target/*.jar'
        }

        stage 'push image'
        image.push()

Learn how to get 20x more performance than Elastic by moving to a Time Series database.

Topics:
docker ,ci/cd ,jenkins pipeline ,java ,jenkins ,containers ,devops ,deployment

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}