By Liptan Biswas, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
Jenkins is an open-source self-hosted automation server. It is very popular amongst the DevOps engineers for implementing continuous integration and continuous delivery in the software development life cycle. Jenkins is written in Java and provides out of the box support for building Apache Ant, Maven, and sbt projects. It can also execute Linux shell and Windows batch scripts. Multiple version control systems such as Git, Mercurial, Subversion, CVS, etc. are fully supported by Jenkins. At least a thousand plugins are available to increase the functionality of the application.
A build in Jenkins can be triggered via several methods such as, after detection of a change in the source code of version control system, or scheduling the build at a specific time, or by invoking a build URL. Once the build is triggered, Jenkins fetches the source code from the repository and the build is started. According to configuration supplied, automatic tests are performed and the output is stored. Jenkins is also capable of delivering the packages generated after a successful build.
This three-part tutorial will guide you through the installation of Jenkins and use it for continuous integration and deployment.
In this first part of the tutorial, we will install the latest version of Jenkins automation server on an Alibaba Cloud Elastic Computer Service (ECS) instance with Ubuntu 16.04 64 bit. We will also set up a secured Nginx reverse proxy to access the Jenkins instance. In the second part, we will create a sample Java web application as a Maven project. We will also go through the process of creating a build job in Jenkins. Finally, in the third part of the tutorial, we will automate the build process. We will also learn to continuously deliver the software using Jenkins.
You can follow the "Quick Start Guide" to create the instance and steps to connect to your instance. This tutorial assumes that you have already created your Alibaba instance and configured "jenkins.example.com" to point to your Ubuntu instance. Once you have connected to your instance via SSH, run the following command to update the repository cache and the base system.
apt update && apt -y upgrade && apt -y autoremove
Instead of running all the commands as root user, it is best to create a sudo user to run all commands. Create a sudo user. You are free to use any username according to your choice.
adduser aliyun
Once the user has been created, add it to the sudo group.
usermod -aG sudo aliyun
Now, switch to the newly created user.
su - aliyun
Set the FQDN or Fully Qualified Domain Name as the hostname of your server. Setting the hostname is not mandatory, however, Jenkins produces warning messages in instances where hostname is incorrectly set.
sudo hostnamectl set-hostname jenkins.example.com
Similarly, add the domain name to your /etc/hosts file.
echo "127.0.0.1 jenkins.example.com" | sudo tee -a /etc/hosts
Since Jenkins is written in Java and we may need to build Java applications in the future, we should proceed to install Java Development Kit or JDK. Jenkins supports both Oracle Java 8 and OpenJDK 8. In this tutorial, we will install Oracle Java version 8. Oracle Java is packed with both Java Runtime (JRE) and JDK. Add the PPA repository for Oracle Java.
sudo apt install -y software-properties-common
sudo add-apt-repository --yes ppa:webupd8team/java
sudo apt update
Install Oracle Java 8.
sudo apt -y install oracle-java8-installer
You can verify if Java has been installed successfully by running java -version command.
aliyun@jenkins:~$ java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
Set the default path for the JAVA_HOME by installing the following package.
sudo apt -y install oracle-java8-set-default
You can now check if JAVA_HOME variable is set by running echo $JAVA_HOME. You may also need to log out and log back in to get the desired output.
aliyun@jenkins:~$ echo $JAVA_HOME
/usr/lib/jvm/java-8-oracle
Jenkins can be easily installed through the repository actively maintained by the project itself. Installation through the repository will also ensure easy upgrades in the future, directly using the apt upgrade command. Import the key used to sign the packages in Jenkins repository. This will ensure that the correct packages are installed.
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
Create a new repository list file for Jenkins.
echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list
Install Jenkins.
sudo apt update
sudo apt -y install jenkins git
Since we are installing Jenkins from the project maintained repository, it should install the latest available version of the application. Git is required to run the Git plugin in Jenkins. To start Jenkins and enable it to automatically start at boot time, run.
sudo systemctl start jenkins
sudo systemctl enable jenkins
You can check the status of the service using the command systemctl status jenkins.
aliyun@jenkins:~$ sudo systemctl status jenkins
● jenkins.service - LSB: Start Jenkins at boot time
Loaded: loaded (/etc/init.d/jenkins; bad; vendor preset: enabled)
Active: active (exited) since Fri 2018-05-04 12:37:03 UTC; 35s ago
Docs: man:systemd-sysv-generator(8)
May 04 12:37:02 jenkins.liptan.tk systemd[1]: Starting LSB: Start Jenkins at boot time...
May 04 12:37:02 jenkins.liptan.tk jenkins[4787]: * Starting Jenkins Automation Server jenkins
To check logs related to Jenkins server itself, run the following command.
tail -f /var/log/jenkins/jenkins.log
The first startup of Jenkins takes few minutes to start. If you find the following line in the output, your application is ready.
aliyun@jenkins:~$ tail -f /var/log/jenkins/jenkins.log
May 02, 2018 2:14:29 PM hudson.WebAppMain$3 run
INFO: Jenkins is fully up and running
Jenkins is now running on your server. Proceed to install Nginx so that we can easily access the Jenkins instance using a domain name.
Note: If you do not have the domain name configured to point at the Alibaba Cloud ECS instance, you can open the port "8080" through the security group of your ECS instance and access your Jenkins instance on http://172.16.0.1:8080, where 172.16.0.1 is the public IP address of your ECS instance. Skip the Install Nginx section and continue to follow the tutorial from Final Setup.
Although Jenkins has a built-in web server to serve the application on the port "8080", in a production system it is not recommended to expose such web servers on the internet. In this tutorial, we will use Nginx as a reverse proxy to forward the requests from the client to the Jenkins server. Setting up a reverse proxy with a domain name also increases the accessibility of the instance, you need not remember the IP address of the instance to access Jenkins.
Install Nginx web server.
sudo apt -y install nginx
Start Nginx and enable the server to automatically start at boot time.
sudo systemctl start nginx
sudo systemctl enable nginx
It is also important to secure the web server with SSL/TLS encryptions as logins and other important data will be sent from the client to the web server and vice versa. If the data being exchanged is not encrypted, a person eavesdropping into the network may obtain the data. In this tutorial, we are going to use the free SSL certificates from the Let's Encrypt CA. If you want to use a more production friendly and trusted SSL, you may purchase SSL certificates from Alibaba Cloud.
Let's Encrypt provides an easy to use tool "Certbot" for requesting and generation of certificates. Add Certbot repository to the system and install Certbot.
sudo add-apt-repository --yes ppa:certbot/certbot
sudo apt update
sudo apt -y install certbot
For Certbot to verify the ownership of the domain, it is important that the domain is pointed towards your ECS instance. If not, certificates for the domain will not be generated and you will be presented with an error. Request for the certificates using Certbot.
sudo certbot certonly --webroot -w /var/www/html -d jenkins.example.com
Once your certificates have been generated, you will see the following output.
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for jenkins.example.com
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/jenkins.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/jenkins.example.com/privkey.pem
...
Create a cron job for auto-renewing the certificates before they expire.
{ sudo crontab -l; echo '36 2 * * * /usr/bin/certbot renew --post-hook "systemctl reload nginx"'; } | sudo crontab -
You can check if the cron job is created by running sudo crontab -l command.
aliyun@jenkins:~$ sudo crontab -l
36 2 * * * /usr/bin/certbot renew --post-hook "systemctl reload nginx"
Create a new Nginx server block for Jenkins reverse proxy.
sudo nano /etc/nginx/sites-available/jenkins
Enter the following configuration in the editor. Make sure to replace all occurrences of the example domain with the actual one.
upstream jenkins {
keepalive 32;
server 127.0.0.1:8080;
}
server {
listen 80;
server_name jenkins.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name jenkins.example.com;
root /var/cache/jenkins/war/;
ssl_certificate /etc/letsencrypt/live/jenkins.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jenkins.example.com/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6].(?!.*SV1)";
access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;
ignore_invalid_headers off;
location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}
location /userContent {
root /var/lib/jenkins/;
if (!-f $request_filename){
rewrite (.*) /$1 last;
break;
}
sendfile on;
}
location @jenkins {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_request_buffering off;
proxy_set_header Connection "";
}
location / {
if ($http_user_agent ~* '(iPhone|iPod)') {
rewrite ^/$ /view/iphone/ redirect;
}
try_files $uri @jenkins;
}
}
Activate the configuration file.
sudo ln -s /etc/nginx/sites-available/jenkins /etc/nginx/sites-enabled/jenkins
You can verify if the configuration file is error free by running sudo nginx -t.
aliyun@jenkins:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart the Nginx web server so that the change in configuration can be reflected.
sudo systemctl restart nginx
Since we are using Nginx reverse proxy to access Jenkins, access to port "8080" is not necessary anymore. If you have enabled access to the port "8080" through the firewall or the security group of your ECS instance, you can safely remove it. To configure Jenkins built-in server to listen to the connections from localhost only, you can change the configuration in the Jenkins default configuration file. Open the configuration file.
sudo nano /etc/default/jenkins
Find the following line at the end of the file.
JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT"
Make the following changes to the configuration.
HTTP_HOST=127.0.0.1
JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT --httpListenAddress=$HTTP_HOST"
Save the file and exit from the editor. Restart your Jenkins instance by running.
sudo systemctl restart jenkins
Now Jenkins built-in server is configured to accept the connections only from the localhost. It can be accessed securely using the Nginx proxy only.
You can access your Jenkins instance through your favorite browser by going to the URL "https://jenkins.example.com".
During the installation, Jenkins generates an initial password. This initial password is required to complete Jenkins setup from the browser. Once you access your Jenkins instance through the browser, you will see that it is asking for an administrator password. Print the initial admin password on the terminal.
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
You should see a similar output.
aliyun@jenkins:~$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
84ae7775fec245e69305c6db08389d69
Copy the password from the terminal and paste it into the browser.
On successful verification of the initial password, setup will ask you for the plugins to install. Since plugins can be easily managed from Jenkins interface, we will go with the Install suggested plugins option. This will install the most popular and useful plugins to extend Jenkins features.
At this stage, setup will install the suggested plugins. It will take a few minutes to get completed. You will see the status of installation of each plugin.
On successful installation of plugins, setup will ask you to create the administrator account. Enter the basic account details asked by Jenkins.
Finally, you will get the message that Jenkins is ready. Proceed to log in and log in using the administrator account you just created. You will be presented with the Jenkins dashboard.
That's it. We have successfully deployed Jenkins automation server on an Alibaba Cloud ECS Ubuntu 16.04. We have also configured Nginx reverse proxy and secured it with Let's Encrypt SSL. Our Jenkins instance is now ready and we can proceed to create our first build job.
In the second part of the tutorial, we will create a sample web-based Java application as Maven project. We will also configure Jenkins to work with JDK, Git, and Maven. Finally, we will set up a Jenkin based build project for the sample application and we will also run our first build.
Alibaba Cloud DevOps Cookbook Part 2 – SSH and ECS Key Pairs
2,599 posts | 762 followers
FollowAlibaba Clouder - May 31, 2018
Alibaba Clouder - July 27, 2020
Alibaba Clouder - June 24, 2019
Alibaba Clouder - May 30, 2018
Alibaba Clouder - July 3, 2019
Alibaba Clouder - April 23, 2019
2,599 posts | 762 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreLearn More
Over 20 million domain, free WHOIS privacy protection.
Learn MoreMore Posts by Alibaba Clouder