|
1 | 1 | 
|
2 | 2 | [](https://github.com/igrigorik/ga-beacon)
|
3 | 3 |
|
4 |
| -Pipeline |
5 |
| -=================== |
6 |
| -This repository is a tutorial of the automatically manage processes such as application build, test and deploy, get a Sonarqube analysis report, docker image build and push to the Docker Hub etc processes with Jenkins Pipeline which is a Docker container. |
| 4 | +# A tutorial about Continuous Integration and Continuous Delivery by Dockerize Jenkins Pipeline |
| 5 | + |
| 6 | +This repository is a tutorial on the automatically management of processes such as application build, test, deploy, getting a code quality report, docker image build, image push to the Docker Hub etc with Jenkins Pipeline which is run on a Docker container. Our goal is to ensure ``Continuous Integration`` and ``Continuous Delivery`` by triggering the pipeline after each push. |
| 7 | + |
| 8 | +That processes we want to auto-manage |
| 9 | +* Code checkout |
| 10 | +* Run tests |
| 11 | +* Compile the code |
| 12 | +* Run Sonarqube analysis on the code |
| 13 | +* Create Docker image |
| 14 | +* Push the image to Docker Hub |
| 15 | +* Pull and run the image |
| 16 | + |
| 17 | +## First step, run up containers |
| 18 | + |
| 19 | +Since one of the goals is to obtain the ``sonarqube`` report of our project, we should be able to access sonarqube from dockerize jenkins. For this reason, we will use ``docker compose`. |
| 20 | + |
| 21 | +`docker-compose.yml`` |
| 22 | +```yml |
| 23 | +version: '3.2' |
| 24 | +services: |
| 25 | + sonarqube: |
| 26 | + build: |
| 27 | + context: sonarqube/ |
| 28 | + ports: |
| 29 | + - 9000:9000 |
| 30 | + - 9092:9092 |
| 31 | + container_name: sonarqube |
| 32 | + jenkins: |
| 33 | + build: |
| 34 | + context: jenkins/ |
| 35 | + privileged: true |
| 36 | + user: root |
| 37 | + ports: |
| 38 | + - 8080:8080 |
| 39 | + - 50000:50000 |
| 40 | + container_name: jenkins |
| 41 | + volumes: |
| 42 | + - /tmp/jenkins:/var/jenkins_home #Remember that, the tmp directory is designed to be wiped on system reboot. |
| 43 | + - /var/run/docker.sock:/var/run/docker.sock |
| 44 | + depends_on: |
| 45 | + - sonarqube |
| 46 | +``` |
| 47 | +
|
| 48 | +Paths of docker files of the containers are specified at context attribute in the docker-compose file. Content of these files as follows. |
| 49 | +
|
| 50 | +``sonarqube/Dockerfile`` |
| 51 | +``` |
| 52 | +FROM sonarqube:6.7-alpine |
| 53 | +``` |
| 54 | + |
| 55 | +``jenkins/Dockerfile`` |
| 56 | +``` |
| 57 | +FROM jenkins:2.60.3 |
| 58 | +``` |
| 59 | + |
| 60 | +If we run the following command in the same directory as the ``docker-compose.yml`` file, the Sonarqube and Jenkins containers will run up. |
| 61 | + |
| 62 | +``` |
| 63 | +docker-compose -f docker-compose.yml up --build |
| 64 | +``` |
| 65 | + |
| 66 | +``` |
| 67 | +docker ps |
| 68 | +
|
| 69 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 70 | +87105432d655 pipeline_jenkins "/bin/tini -- /usr..." About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp jenkins |
| 71 | +f5bed5ba3266 pipeline_sonarqube "./bin/run.sh" About a minute ago Up About a minute 0.0.0.0:9000->9000/tcp, 0.0.0.0:9092->9092/tcp sonarqube |
| 72 | +``` |
| 73 | + |
| 74 | +## GitHub configuration |
| 75 | +We'll define a service on Github to call the ``Jenkins Github`` webhook because we want to trigger the pipeline we will define whenever a push is made to our repository. To do this go to **Settings -> integrations & Services.** The ``Jenkins Github plugin`` should be shown on the list of available services as below. |
| 76 | + |
| 77 | + |
| 78 | + |
| 79 | +After this, we should be define our access URL of dockerize Jenkins container as **Jenkins URL** by adding ``/github-webhook/`` and add a new service. |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | +The next step is that create an ``SSH key`` for Jenkins user and define it as a ``Deploy keys`` on our GitHub repository. |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +When the steps are taken correctly, the following connection request should return a result like this. |
| 88 | +``` |
| 89 | + |
| 90 | +PTY allocation request failed on channel 0 |
| 91 | +Hi <your github username>/<repository name>! You've successfully authenticated, but GitHub does not provide shell access. |
| 92 | +Connection to github.com closed. |
| 93 | +``` |
| 94 | + |
| 95 | +## Jenkins configuration |
| 96 | + |
| 97 | +We have configured Jenkins int the docker compose file to run on 8080 HTTP port therefore if we visit http://localhost:8080 we will be greeted by a screen like this. |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +We need the admin password to proceed to installation. It's stored ``/var/jenkins_home/secrets/initialAdminPassword`` directory and also written as output on the console when Jenkins run up. |
| 102 | + |
| 103 | +``` |
| 104 | +jenkins | ************************************************************* |
| 105 | +jenkins | |
| 106 | +jenkins | Jenkins initial setup is required. An admin user has been created and a password generated. |
| 107 | +jenkins | Please use the following password to proceed to installation: |
| 108 | +jenkins | |
| 109 | +jenkins | 45638c79cecd4f43962da2933980197e |
| 110 | +jenkins | |
| 111 | +jenkins | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword |
| 112 | +jenkins | |
| 113 | +jenkins | ************************************************************* |
| 114 | +``` |
| 115 | + |
| 116 | +To access the password from the container. |
| 117 | + |
| 118 | +``` |
| 119 | +docker exec -it jenkins sh |
| 120 | +/ $ cat /var/jenkins_home/secrets/initialAdminPassword |
| 121 | +``` |
| 122 | + |
| 123 | +After entering the password, we will be download recommended plugins and define ``admin user``. |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | + |
| 128 | + |
| 129 | + |
| 130 | + |
| 131 | +After clicking **Save and Finish** and **Start using Jenkins** buttons, we should be seeing the Jenkins homepage. One of the seven goals listed above is that we should be docker image building in dockerize Jenkins. Please look at the volume definitions for Jenkins in the compose file. |
| 132 | +``` |
| 133 | +- /var/run/docker.sock:/var/run/docker.sock |
| 134 | +``` |
| 135 | + |
| 136 | +The purpose here is to communicate between the ``Docker Daemon`` and the ``Docker Client``(_we will install it on the Jenkins_) over the socket. Like the docker client, we also need ``Maven`` to compile the application to be checked out. For the installation of these tools, we need to perform ``Maven`` and ``Docker Client`` installs under _Manage Jenkins -> Global Tool Configuration_ menu. |
| 137 | + |
| 138 | + |
| 139 | + |
| 140 | +We added Maven and Docker installer and checked ``Install automatically`` checkbox. These tools are installed by Jenkins when our script(_Jenkins file_) first runs. We give ``myMaven`` and ``myDocker`` names to the tools. We will access these tools with this names in the script file. |
| 141 | + |
| 142 | +Since we will perform some operations such as ``checkout`` and ``push image to Docker Hub`` on the script file, We need to define the ``Docker Hub Credentials`` and if _we are using a **private repo**, in addition, we must define ``Github credentials``. |
| 143 | +These definitions are performed under _Jenkins Home Page -> Credentials -> Global credentials (unrestricted) -> Add Credentials_ menu. |
| 144 | + |
| 145 | + |
| 146 | + |
| 147 | +We will use the value we entered in the ``ID`` field to Docker Login in the script file. Now, we define pipeline under _Jenkins Home Page -> New Item_ menu. |
| 148 | + |
| 149 | + |
| 150 | + |
| 151 | +In this step, we select ``GitHub hook trigger for GITScm pooling`` options for automatic run of the pipeline by ``Github hook`` call. |
| 152 | + |
| 153 | + |
| 154 | + |
| 155 | +Also in Pipeline section, we ``select Pipeline script from SCM`` as Definition, define GitHub repository and branch, and specify script location(_Jenkins file_). |
| 156 | + |
| 157 | + |
| 158 | + |
| 159 | +After that, when a push is done to the remote repository or when you manually trigger the pipeline by ``build now`` option, the steps described in Jenkins file will be executed. |
| 160 | + |
| 161 | +## Review important points of the Jenkins file |
| 162 | + |
| 163 | +``` |
| 164 | +stage('Initialize'){ |
| 165 | + def dockerHome = tool 'myDocker' |
| 166 | + def mavenHome = tool 'myMaven' |
| 167 | + env.PATH = "${dockerHome}/bin:${mavenHome}/bin:${env.PATH}" |
| 168 | +} |
| 169 | +``` |
| 170 | + |
| 171 | +The ``Maven`` and ``Docker client`` tools we have defined in Jenkins under _Global Tool Configuration_ menu are added to the ``PATH environment variable`` for using these tools with ``sh command``. |
| 172 | + |
| 173 | +``` |
| 174 | +stage('Push to Docker Registry'){ |
| 175 | + withCredentials([usernamePassword(credentialsId: 'dockerHubAccount', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { |
| 176 | + pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD) |
| 177 | + } |
| 178 | +} |
| 179 | +``` |
| 180 | + |
| 181 | +``withCredentials`` provided by ``Jenkins Credentials Binding Plugin`` and bind credentials to variables. We passed **dockerHubAccount** value with ``credentialsId`` parameter. Remember that, dockerHubAccount value is Docker Hub credentials ID we have defined it under _Jenkins Home Page -> Credentials -> Global credentials (unrestricted) -> Add Credentials_ menu. In this way, we access to username and password information of the account for login. |
| 182 | + |
| 183 | +## Sonarqube configuration |
| 184 | + |
| 185 | +For ``Sonarqube`` we have made the following definitions in the ``pom.xml`` file of the project. |
| 186 | + |
| 187 | +```xml |
| 188 | +<sonar.host.url>http://sonarqube:9000</sonar.host.url> |
| 189 | +... |
| 190 | +<dependencies> |
| 191 | +... |
| 192 | + <dependency> |
| 193 | + <groupId>org.codehaus.mojo</groupId> |
| 194 | + <artifactId>sonar-maven-plugin</artifactId> |
| 195 | + <version>2.7.1</version> |
| 196 | + <type>maven-plugin</type> |
| 197 | + </dependency> |
| 198 | +... |
| 199 | +</dependencies> |
| 200 | +``` |
| 201 | + |
| 202 | +In the docker compose file, we gave the ``sonarqube`` name to the Sonarqube container, so in the pom.xml file the sonar URL was defined as http://sonarqube:9000. |
0 commit comments