top of page
Blog SO Labs na Íntegra
Gustavo Ferreira

Construindo uma esteira com integração contínua utilizando GIT, jenkins, testes e docker.

Bom, hoje vamos conversar sobre jenkins e devops, vamos montar uma esteira (pipeline) utilizando os dois recursos do jenkins pipeline e free style, dentro do nosso pipeline vamos subir nossa imagem docker, puxar o código de um repositório github, realizar os testes utilizando o selenium, sonarqube, para este ambiente vamos utilizar o maven para compilação, tomcat será o nosso servidor web.


1.0 - configurar o ambiente, neste cenário teremos 2 ambientes o de teste e de produção vamos utilizar o contêiner (docker), e o docker-compose como orquestrador, logo abaixo nosso arquivo docker-compose.yml com as configurações do ambiente, basta salvar o arquivo na pasta e utilizar o comando docker up para subir o ambiente.


1.1 - instalar o chrome e o driver do selenium deve ser igual à versão instalada do chrome


1.2 - instalar o java SDK,e adicionar o SDK a PATH como variável do ambiente


1.3 - baixar e instalar MVN(Maven), e adicionar PATH como variável do ambiente


1.4 - subir o servidor tomcat e do jenkins


1.5 – subir servidor do ambiente de teste com as configurações do docker-compose


version"3"

services:
 pg-tasks:
 container_namepg-tasks
 imagepostgres:9.6
 ports:
            - 5433:5432
 environment:
            - POSTGRES_DB=tasks
            - POSTGRES_PASSWORD=password

 sonarqube:
 container_namesonar
 imagesonarqube:7.9.2-community
 ports:
            - "9000:9000"
 networks:
            - sonarnet
 environment:
            - sonar.jdbc.url=jdbc:postgresql://pg-sonar:5432/sonar
 depends_on:
            - pg-sonar
 volumes:
            - sonarqube_conf:/opt/sonarqube/conf
            - sonarqube_data:/opt/sonarqube/data
            - sonarqube_extensions:/opt/sonarqube/extensions
            - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins

 pg-sonar:
 container_namepg-sonar
 imagepostgres:9.6
 networks:
            - sonarnet
 environment:
            - POSTGRES_USER=sonar
            - POSTGRES_PASSWORD=sonar
 volumes:
            - postgresql:/var/lib/postgresql
            - postgresql_data:/var/lib/postgresql/data

 selenium-hub:
 imageselenium/hub:3.141.59-zinc
 container_nameselenium-hub
 networks:
            - seleniumGrid
 ports:
            - "4444:4444"

 chrome:
 imageselenium/node-chrome:3.141.59-zinc
 container_nameChrome-1
 networks:
            - seleniumGrid
 depends_on:
            - selenium-hub
 environment:
            - HUB_HOST=selenium-hub
            - HUB_PORT=4444
            - NODE_MAX_INSTANCES=2
            - NODE_MAX_SESSIONS=2

 chrome2:
 imageselenium/node-chrome:3.141.59-zinc
 container_nameChrome-2
 networks:
            - seleniumGrid
 depends_on:
            - selenium-hub
 environment:
            - HUB_HOST=selenium-hub
            - HUB_PORT=4444
            - NODE_MAX_INSTANCES=2
            - NODE_MAX_SESSIONS=2

networks:
 sonarnet:
 seleniumGrid:

volumes:
 sonarqube_conf:
 sonarqube_data:
 sonarqube_extensions:
 sonarqube_bundled-plugins:
 postgresql:
 postgresql_data:

sonarqube:
 container_namesonar
 imagesonarqube:7.9.2-community
 ports:
      - "9000:9000"
 networks:
      - sonarnet
 environment:
      - sonar.jdbc.url=jdbc:postgresql://pg-sonar:5432/sonar
 depends_on:
      - pg-sonar
 volumes:
      - sonarqube_conf:/opt/sonarqube/conf
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins

 pg-sonar:
 container_namepg-sonar
 imagepostgres:9.6
 networks:
      - sonarnet
 environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
 volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data

networks:
 sonarnet:

volumes:
 sonarqube_conf:
 sonarqube_data:
 sonarqube_extensions:
 sonarqube_bundled-plugins:
 postgresql:
 postgresql_data:


2.0 – iniciando os trabalhos com o jobs tipo free style como na imagem abaixo:


2.1 – inserir credencias e autenticação do git, sonarqube e tomcat.





3.0 – vamos realizar o nosso teste de qualidade e segurança do código usando o sonarqube https://www.sonarqube.org/


3.1 – integrando o sonarqube e quality gate na esteira do jenkins




4.0 – realizando teste funcional utilizando o selenium como nas imagens abaixo


5.0 – vamos agora construir o mesmo projeto porém utilizando o pipeline do jenkins


5.1 – inserir o código abaixo no pipeline


pipeline {
 agent any
 stages {
 stage ('Build Backend') {
 steps {
 bat 'mvn clean package -DskipTests=true'
            }
        }
 stage ('Unit Test') {
 steps {
 bat 'mvn test'
            }
        }
 stage ('Sonar analysis') {
 environment {
                scannerHome = tool 'SONAR_SCANNER'
            }
 steps {
                withSonarQubeEnv('SONAR_LOCAL') {
 bat "${scannerHome}/bin/sonar-scanner -e -Dsonar.projectKey=DeploBack -Dsonar.host.url=http://127.0.0.1:9000 -Dsonar.login=ee946d1fb6cbc1a9cf240c8114506cbff3a08a41 -Dsonar.java.binaries=target -Dsonar.coverage.exclusions=**/.mvn/**,**/src/test/**,**/model/**,**Applicantion.java"
                }
            }
        }
 stage ('Quality Gate') {
 options {
            timeout(time: 5, unit: 'MINUTES')
            retry(2)
            }
 steps {
                sleep(10){
                    waitForQualityGate(abortPipeline: true)
                }
            }
        }
 stage ('Deploy Backend') {
 steps {
                deploy adapters: [tomcat8(credentialsId: 'TomcatLogin2'path: ''url: 'http://127.0.0.1:8001/')], contextPath: 'tasks-backend'war: 'target\\tasks-backend.war'
            }
        }
 stage ('API Test') {
 steps {
                dir('api-test') {
                    git credentialsId: 'github_login'url: 'https://github.com/gugafer/tasks-api-test'
 bat 'mvn test'
                }
            }
        }
 stage ('Deply Frontend') {
 steps {
                dir('frontend') {
                    git credentialsId: 'github_login'url: 'https://github.com/gugafer/tasks-frontend'
 bat 'mvn clean package' 
                    deploy adapters: [tomcat8(credentialsId: 'TomcatLogin2'path: ''url: 'http://127.0.0.1:8001/')], contextPath: 'tasks'war: 'target\\tasks.war'
 
                }
            }
        }
 stage ('Functional Test') {
 steps {
                dir('functional-test') {
                    git credentialsId: 'github_login'url: 'https://github.com/gugafer/tasks-functional-test'
 bat 'mvn test'
                }
            }
        }
 stage ('Deploy Prod') {
 steps {
 bat 'docker-compose build'
 bat 'docker-compose up -d'
            }
        }
 stage ('Health check') {
 steps {
                sleep(20)
                dir('functional-test') {
 bat 'mvn verify'
                }
            }
        }      
    }
 post{
 always{
            junit allowEmptyResults: truetestResults: 'target/surefire-reports/*.xml, functional-test/target/surefire-reports/*.xml, functional-test/target/failsafe-reports/*.xml'
            archiveArtifacts artifacts: 'target/tasks-backend.war, frontend/target/tasks.war'followSymlinks: falseonlyIfSuccessful: true
        }
    }
}

5.2 – inicializar o docker-compose de produção como abaixo:


version"3"
services:
 db:
 container_namepg-prod
 imagepostgres:9.6
 networks:
      - prod_net_back
 environment:
      - POSTGRES_PASSWORD=passwd
      - POSTGRES_DB=tasks
 volumes:
      - prod_postgresql:/var/lib/postgresql
      - prod_postgresql_data:/var/lib/postgresql/data

 backend:
 container_namebackend-prod
 imageback_prod:build_${BUILD_NUMBER}
 build:
 context.
 args:
        - WAR_FILE=target/tasks-backend.war
        - CONTEXT=tasks-backend
 networks:
      - prod_net_back
      - prod_net_front
 #ports:
 #  - 9998:8080
 environment:
      - DATABASE_HOST=db
      - DATABASE_PORT=5432
      - DATABASE_USER=postgres
      - DATABASE_PASSWD=passwd
      - DATABASE_UPDATE=none
 depends_on:
      - db

 frontend:
 container_namefrontend-prod
 imagefront_prod:build_${BUILD_NUMBER}
 build:
 context.
 args:
          - WAR_FILE=frontend/target/tasks.war
          - CONTEXT=tasks
 networks:
      - prod_net_front
 ports:
      - 9999:8080
 environment:
      - BACKEND_HOST=backend
      - BACKEND_PORT=8080
      - APP_VERSION=build_${BUILD_NUMBER}
 #depends_on:
 #  - backend

networks:
 prod_net_front:
 prod_net_back:

volumes:
 prod_postgresql:
 prod_postgresql_data:

5.3 – Por fim nossa esteira pronta, versionada e automatizada, veja nas imagens abaixo






 

Gustavo Ferreira


Arquiteto Cloud, DevOps, Site Reliability Engineering (SRE)

Membro do blog space one labs

Certificação Comptia Cloud+

bottom of page