Skip to end of metadata
Go to start of metadata

In situations where you have existing web sites on your server, you may find it useful to run Jenkins (or the servlet container that Jenkins runs in) behind Nginx, so that you can bind Jenkins to the part of a bigger website that you may have. This document discusses some of the approaches for doing this.

When a request arrives for certain URLs, Nginx becomes a proxy and further forward that request to Jenkins, then it forwards the response back to the client. A typical set up for mod_proxy would look like this:

upstream jenkins {
  keepalive 32; # keepalive connections
  server 127.0.0.1:8080; # jenkins ip and port
}
 
server {
  listen          80;       # Listen on port 80 for IPv4 requests

  server_name     jenkins.example.com;

  #this is the jenkins web root directory (mentioned in the /etc/default/jenkins file)
  root            /var/run/jenkins/war/;

  access_log      /var/log/nginx/jenkins/access.log;
  error_log       /var/log/nginx/jenkins/error.log;
  ignore_invalid_headers off; #pass through headers from Jenkins which are considered invalid by Nginx server.

  location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
    #rewrite all static files into requests to the root
    #E.g /static/12345678/css/something.css will become /css/something.css
    rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
  }

  location /userContent {
    #have nginx handle all the static requests to the userContent folder files
    #note : This is the $JENKINS_HOME dir
	root /var/lib/jenkins/;
    if (!-f $request_filename){
      #this file does not exist, might be a directory or a /**view** url
      rewrite (.*) /$1 last;
	  break;
    }
	sendfile on;
  }

  location / {
      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;

      #this is the maximum upload size
      client_max_body_size       10m;
      client_body_buffer_size    128k;

      proxy_connect_timeout      90;
      proxy_send_timeout         90;
      proxy_read_timeout         90;
      proxy_buffering            off;
      proxy_request_buffering    off; # Required for HTTP CLI commands in Jenkins > 2.54
      proxy_set_header Connection ""; # Clear for keepalive
  }

}

This assumes that you run Jenkins on port 8080. Remember to create the folder /var/log/nginx/jenkins.

For this set up to work, the context path of Jenkins must be the same between your Nginx and Jenkins (that is, you can't run Jenkins on http://localhost:8081/ci and have it exposed at http://localhost:80/jenkins).

Set the context path by modifying the hudson.xml configuration file and adding --prefix=/hudson (or similar) to the <arguments> entry.

If you are having problems with some paths (eg folders) with Blue Ocean, you may need to add the following snippet to your proxy configuration:

if ($request_uri ~* "/blue(/.*)") {
    proxy_pass http://YOUR_SERVER_IP:YOUR_JENKINS_PORT/blue$1;
    break;
}

To give nginx permission to read Jenkins web root folder, add nginx to Jenkins group: 

useradd \-aG Jenkins nginx

If you are experiencing timeouts when attempting to run long CLI commands through a proxy in Jenkins > 2.80, you can increase the proxy_read_timeout setting as necessary. Older versions of Jenkins may not respect the proxy_read_timeout setting.

If you are experiencing the following error when attempting to run long CLI commands in Jenkins > 2.80, and Jenkins is running behind Nginx, it is probably due to Nginx timing out the CLI connection. You can increase the proxy_read_timeout setting as necessary so the command will complete successfully. Versions of Jenkins before 2.80 may not respect the proxy_read_timeout setting.

WARNING: null
hudson.cli.DiagnosedStreamCorruptionException
Read back: 0x00 0x00 0x00 0x1e 0x07 'Started reverse-proxy-test #68' 0x00 0x00 0x00 0x01 0x07 0x0a
Read ahead: 
Diagnosis problem:
    java.io.IOException: Premature EOF
    	at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:565)
    	...
	at hudson.cli.FlightRecorderInputStream.analyzeCrash(FlightRecorderInputStream.java:82)
	at hudson.cli.PlainCLIProtocol$EitherSide$Reader.run(PlainCLIProtocol.java:153)
Caused by: java.io.IOException: Premature EOF
	at sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:565)
	...
	at java.io.DataInputStream.readInt(DataInputStream.java:387)
	at hudson.cli.PlainCLIProtocol$EitherSide$Reader.run(PlainCLIProtocol.java:111)

5 Comments

  1. We should warn people about broken things in the first paragraph, not the last one!

  2. Is


    # Optional configuration to detect and redirect iPhones
        if ($http_user_agent ~* '(iPhone|iPod)') {
          rewrite ^/$ /view/iphone/ redirect;
        }

    no longer pertinent? It seems that older versions of Jenkins may have had this view, but when I navigate to view/iphone now it gives me a 404 page.

    1. yeah I think that can be removed (I did) as have never come across that, seems from early days of iphone perhaps... 

  3. Greetings ,

    We are facing issues with some paths (eg folders) with Blue Ocean , running Jenkins behind Nginx.

    Please find below the Nginx configurations:

    Can you please confirm where the suggested solution should be defined in the below configurations :

    or if some other suggestions.


    if ($request_uri ~* "/blue(/.*)") {
        proxy_pass http://YOUR_SERVER_IP:YOUR_JENKINS_PORT/blue$1;
        break;
    }

    ################################################################################

    server {

      listen 8999;

      ssl on;

      ssl_certificate /swa/certs/project.tool.crt;

      ssl_certificate_key /swa/certs/project.tool.key;

      ssl_protocols TLSv1.2;

      ssl_ciphers HIGH:!aNULL:!MD5;


      ssl_session_cache   shared:SSL:10m;

      ssl_session_timeout 10m;


      keepalive_timeout 60;

      sendfile          on;

      tcp_nopush        on;

      tcp_nodelay       on;

      proxy_buffering   off;

      access_log        /var/log/nginx/jenkins_access.log;

      port_in_redirect  off;


      client_max_body_size      0;

      client_body_buffer_size   128k;

      client_header_timeout     3m;

      client_body_timeout       3m;

      send_timeout              3m;


      location / {

         proxy_pass http://jenkins:8080/;

         proxy_read_timeout        900;

         proxy_max_temp_file_size  0;


         proxy_set_header   X-Forwarded-Host $host;

         proxy_set_header   X-Forwarded-Server $host;

         proxy_set_header   X-Forwarded-Proto $scheme;

         proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

         proxy_set_header   X-Real-IP $remote_addr;

         proxy_redirect     off;

      }

    }


    The error while accessing the job inside folder through blue ocean :

    The requested URL /LPFG/blue/organizations/jenkins/product-desktop-air-operations/spa-air-flight-status was not found on this server.


    Apache/2.4.25 (Debian) Server at jenkins-tools.swacorp.com Port 443