Skip to content

Commit 18e01ff

Browse files
committed
Readme and Jenkins files updated
1 parent 3329eb3 commit 18e01ff

File tree

18 files changed

+214
-17
lines changed

18 files changed

+214
-17
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ RUN mvn clean install
1010

1111
EXPOSE 8090
1212

13-
ENTRYPOINT [ "java", "-jar", "/pipeline/target/pipeline.jar"]
13+
ENTRYPOINT [ "java", "-jar", "/pipeline/target/jenkins-pipeline.jar"]

Jenkinsfile

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
def CONTAINER_NAME="pipeline"
1+
def CONTAINER_NAME="jenkins-pipeline"
2+
def CONTAINER_TAG="lates"
23
def DOCKER_HUB_USER="hakdogan"
34
def HTTP_PORT="8090"
45

@@ -31,17 +32,17 @@ node {
3132
}
3233

3334
stage('Image Build'){
34-
imageBuild(CONTAINER_NAME)
35+
imageBuild(CONTAINER_NAME, CONTAINER_TAG)
3536
}
3637

3738
stage('Push to Docker Registry'){
3839
withCredentials([usernamePassword(credentialsId: 'dockerHubAccount', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
39-
pushToImage(CONTAINER_NAME, USERNAME, PASSWORD)
40+
pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD)
4041
}
4142
}
4243

4344
stage('Run App'){
44-
runApp(CONTAINER_NAME, DOCKER_HUB_USER, HTTP_PORT)
45+
runApp(CONTAINER_NAME, CONTAINER_TAG, DOCKER_HUB_USER, HTTP_PORT)
4546
}
4647

4748
}
@@ -53,20 +54,20 @@ def imagePrune(containerName){
5354
} catch(error){}
5455
}
5556

56-
def imageBuild(containerName){
57-
sh "docker build -t $containerName:latest -t $containerName --pull --no-cache ."
57+
def imageBuild(containerName, tag){
58+
sh "docker build -t $containerName:$tag -t $containerName --pull --no-cache ."
5859
echo "Image build complete"
5960
}
6061

61-
def pushToImage(containerName, dockerUser, dockerPassword){
62+
def pushToImage(containerName, tag, dockerUser, dockerPassword){
6263
sh "docker login -u $dockerUser -p $dockerPassword"
63-
sh "docker tag $containerName:latest $dockerUser/$containerName:latest"
64-
sh "docker push $dockerUser/$containerName:latest"
64+
sh "docker tag $containerName:$tag $dockerUser/$containerName:$tag"
65+
sh "docker push $dockerUser/$containerName:$tag"
6566
echo "Image push complete"
6667
}
6768

68-
def runApp(containerName, dockerHubUser, httpPort){
69+
def runApp(containerName, tag, dockerHubUser, httpPort){
6970
sh "docker pull $dockerHubUser/$containerName"
70-
sh "docker run -d --rm -p $httpPort:$httpPort --name $containerName $dockerHubUser/$containerName:latest"
71+
sh "docker run -d --rm -p $httpPort:$httpPort --name $containerName $dockerHubUser/$containerName:$tag"
7172
echo "Application started on port: ${httpPort} (http)"
7273
}

README.md

Lines changed: 199 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,202 @@
11
!["Docker Pulls](https://img.shields.io/docker/pulls/hakdogan/pipeline.svg)
22
[![Analytics](https://ga-beacon.appspot.com/UA-110069051-1/pipeline/readme)](https://github.com/igrigorik/ga-beacon)
33

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+
![](image:images/001.png)
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+
![](image:images/002.png)
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+
![](image:images/003.png)
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+
![](image:images/004.png)
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+
![](image:images/005.png)
126+
127+
![](image:images/006.png)
128+
129+
![](image:images/007.png)
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+
![](image:images/008.png)
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+
![](image:images/009.png)
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+
![](image:images/010.png)
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+
![](image:images/011.png)
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+
![](image:images/012.png)
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.

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ services:
1717
- 50000:50000
1818
container_name: jenkins
1919
volumes:
20-
- /tmp/jenkins:/var/jenkins_home
20+
- /tmp/jenkins:/var/jenkins_home #Remember that, the tmp directory is designed to be wiped on system reboot.
2121
- /var/run/docker.sock:/var/run/docker.sock
2222
depends_on:
2323
- sonarqube

images/001.png

446 KB
Loading

images/002.png

485 KB
Loading

images/003.png

553 KB
Loading

images/004.png

808 KB
Loading

images/005.png

873 KB
Loading

images/006.png

818 KB
Loading

images/007.png

755 KB
Loading

images/008.png

364 KB
Loading

images/009.png

381 KB
Loading

images/010.png

568 KB
Loading

images/011.png

111 KB
Loading

images/012.png

221 KB
Loading

images/013.png

572 KB
Loading

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>com.kodcu</groupId>
7-
<artifactId>pipeline</artifactId>
7+
<artifactId>jenkins-pipeline</artifactId>
88
<version>1.0-SNAPSHOT</version>
99

1010
<properties>

0 commit comments

Comments
 (0)