(Last Updated On: April 9, 2019)

Question: How can I put Jenkins behind Nginx reverse proxy and Let’s Encrypt SSL certificate?. Jenkins is a powerful open source automation server built for automating repetitive tasks and to fasten continuous integration and delivery of Applications.

This short tutorial will discuss how you can configure Nginx to work as reverse Proxy for Jenkins server. The assumption is that you have a working Jenkins server, but our guides can be of help setting up Jenkins Server.

How to install Jenkins on CentOS 7, Ubuntu, Arch Linux.

Step 1: Install Nginx

You need to start by installing Nginx Web server on your Linux Distribution. Here are the commands for installing Nginx on common Linux distributions.

# CentOS / RHEL
$ sudo yum -y install nginx vim

# Fedora
$ sudo dnf -y install nginx vim

# Ubuntu / Debian
$ sudo apt-get -y install nginx vim

Step 2: Install Cerbot tool

Next is the installation of Certbot tool that is used to obtain Let’s Encrypt SSL certificate. Download and install certbot-auto command line tool.

curl -sL https://dl.eff.org/certbot-auto | sudo tee /usr/local/bin/certbot-auto

Give the script an execution bit.

sudo chmod +x /usr/local/bin/certbot-auto

Check if working:

$ certbot-auto --version
certbot 0.33.1

When asked to confirm installation of dependencies, answer “yes“.

Dependencies Resolved

===========================================================================
 Package              Arch      Version                   Repository  Size
===========================================================================
Installing:
 augeas-libs          x86_64    1.4.0-6.el7_6.1           updates    355 k
 libffi-devel         x86_64    3.0.13-18.el7             base        23 k
 mod_ssl              x86_64    1:2.4.6-88.el7.centos     base       112 k
 python-devel         x86_64    2.7.5-76.el7              base       398 k
 python-tools         x86_64    2.7.5-76.el7              base       856 k
 python-virtualenv    noarch    15.1.0-2.el7              base       1.7 M
 python2-pip          noarch    8.1.2-8.el7               epel       1.7 M
 redhat-rpm-config    noarch    9.1.0-87.el7.centos       base        81 k
Installing for dependencies:
 dwz                  x86_64    0.11-3.el7                base        99 k
 libXft               x86_64    2.3.2-2.el7               base        58 k
 libXrender           x86_64    0.9.10-1.el7              base        26 k
 perl-srpm-macros     noarch    1-8.el7                   base       4.6 k
 tcl                  x86_64    1:8.5.13-8.el7            base       1.9 M
 tix                  x86_64    1:8.4.3-12.el7            base       254 k
 tk                   x86_64    1:8.5.13-6.el7            base       1.4 M
 tkinter              x86_64    2.7.5-76.el7              base       326 k
 zip                  x86_64    3.0-11.el7                base       260 k

Transaction Summary
===========================================================================
Install  8 Packages (+9 Dependent packages)

Total download size: 9.5 M
Installed size: 26 M
Is this ok [y/d/N]: y

Step 4: Request for Let’s Encrypt SSL Certiticate

You need a working DNS for the domain or subdomain used by the Jenkins server. In my demonstration, I’m using jenkins.computingforgeeks.com.

You also need to open port 80 to be able to get the certificate, but only if you have an active firewall.

# CentOS 7
$ sudo firewall-cmd --add-service={http,https} --permanent
$ sudo firewall-cmd --reload

# Ubuntu / Debian
$ sudo ufw allow proto tcp from any to any port 80,443
$ sudo ufw status

Once that is done, get Let’s Encrypt Certificate:

export DOMAIN="jenkins.example.com"
export ALERTS_EMAIL="[email protected]"
sudo systemctl stop nginx
sudo /usr/local/bin/certbot-auto certonly --standalone -d $DOMAIN --preferred-challenges http --agree-tos -n -m $ALERTS_EMAIL --keep-until-expiring

Sample output:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for jenkins.computingforgeeks.com
Waiting for verification…
Cleaning up challenges
IMPORTANT NOTES:
Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/jenkins.computingforgeeks.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/jenkins.computingforgeeks.com/privkey.pem
Your cert will expire on 2019-07-08. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew all of your certificates, run
"certbot-auto renew"
Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Step 5: Configure Nginx

Create an Nginx configuration file for Jenkins.

sudo vim /etc/nginx/conf.d/jenkins.conf

Paste below to the file.

################################################
# Jenkins Proxy configuration with SSL
#################################################
upstream jenkins {
  server 127.0.0.1:8080 fail_timeout=0;
}
 
server {
  listen 80;
  server_name jenkins.example.com;
  return 301 https://$host$request_uri;
}
 
server {
  listen 443 ssl;
  server_name jenkins.example.com;
 
  ssl_certificate /etc/letsencrypt/live/jenkins.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/jenkins.example.com/privkey.pem;
 
  location / {
    proxy_set_header        Host $host:$server_port;
    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_redirect http:// https://;
    proxy_pass              http://jenkins;
    # Required for new HTTP-based CLI
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_buffering off; # Required for HTTP-based CLI to work over SSL
    # workaround for https://issues.jenkins-ci.org/browse/JENKINS-45651
    add_header 'X-SSH-Endpoint' 'jenkins.example.com:50022' always;
  }
}

Substitute all occurrences of example.com with your correct domain name. When done, validate nginx configuration.

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If the configuration looks fine, start nginx and set it to start at boot.

sudo systemctl restart nginx
sudo systemctl enable nginx

Step 6: Access Jenkins Web Interface

Access Jenkins web interface on http://jenkins.example.com.

The Jenkins Dashboard should show after login.

You have successfully configured Nginx as Reverse proxy to Jenkins server with Let’s Encrypt SSL certificate.

Other Jenkins related Articles:

How to Manage Users and Roles in Jenkins

Running Jenkins Server in Docker Container with Systemd