Reverse proxy - Issues
Symptoms
An error message is displayed in the "Manage Jenkins" page
It appears that your reverse proxy setup is broken
| This message can also appear if you don’t access Jenkins through a reverse proxy: Make sure the Jenkins URL configured in the System Configuration matches the URL you’re using to access Jenkins. |
Background
For a reverse proxy to work correctly, it needs to rewrite both the request and the response. Request rewriting involves receiving an inbound HTTP call and then making a forwarding request to Jenkins (sometimes with some HTTP headers modified, sometimes not). Failing to configure the request rewriting is easy to catch, because you just won’t see any pages at all.
But correct reverse proxying also involves one of two options, EITHER
-
rewrite the response with a "Location" header in the response, which is used during redirects. Jenkins sends
Location: http://actual.server:8080/jenkins/foobarand the reverse proxy must rewrite it toLocation: http://nice.name/jenkins/foobar. Unfortunately, failing to configure this correctly is harder to catch; OR -
set the headers
X-Forwarded-Host(and perhapsX-Forwarded-Port) on the forwarded request. Jenkins will parse those headers and generate all the redirects and other links on the basis of those headers. Depending on your reverse proxy it may be easier to setX-Forwarded-HostandX-Forwarded-Portto the hostname and port in the originalHostheader respectively or it may be easier to just pass the originalHostheader through asX-Forwarded-Hostand delete theX-Forwarded-Port# header from the request. You will also need to set theX-Forwarded-Protoheader if your reverse proxy is changing fromhttpstohttpor vice-versa.
Jenkins has proactive monitoring to make sure this is configured correctly. It uses XmlHttpRequest to request a specific URL in Jenkins (via relative path, so this will always get through provided the request is properly rewritten), which will then redirect the user to another page in Jenkins (this only works correctly if you configured the response rewriting correctly), which then returns 200.
This error message indicates that this test is failing - and the most likely cause is that the response rewriting is misconfigured. See the configuration examples for additional tips about configuring a reverse proxy.
Be sure to set the X-Forwarded-Proto header if your reverse proxy is
accessed via HTTPS and then Jenkins itself is accessed via HTTP i.e.
proxying HTTPS to HTTP.
Context path
The context path is the prefix of a URL path.
The Jenkins controller and the reverse proxy must use the same context path.
For example, if the Jenkins controller URL is https://www.example.com/jenkins/ then the --prefix=/jenkins argument must be included in the Jenkins controller command line arguments.
Set the context path when using the Linux packages by running systemctl edit jenkins and adding the following:
[Service]
Environment="JENKINS_PREFIX=/jenkins"
Set the context path on Windows controllers by including the --prefix command line argument in the jenkins.xml file in the installation directory.
Ensure that Jenkins is running at the context path where your reverse proxy is serving Jenkins. You will have the least pain if you keep to this principle.
The --prefix command line argument is not needed if the context path is empty.
For example, the URL https://jenkins.example.com/ has an empty context path.
Changing the context path of Jenkins with a reverse proxy is fraught with danger. There are many URLs that must be rewritten. Even if you rewrite all the URLs in HTML files, you may miss some in JavaScript, CSS, or XML resources.
While it is technically possible to use rewrite rules to change the context path,
you should be aware that it would be a lot of work to find and fix everything in
your rewrite rules and the reverse proxy will spend most of its time rewriting
responses from Jenkins.
Much easier to change Jenkins to run at the context path your reverse proxy is
expecting, e.g. if your reverse proxy is forwarding requests at
https://manchu.example.org/foobar/ to Jenkins then you could just use
java -jar jenkins.war --prefix=/foobar to start jenkins using
/foobar as the context path
Further Diagnosis
For further diagnosis, try using cURL:
BASE=administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor
curl -iL -e http://your.reverse.proxy/jenkins/manage \
http://your.reverse.proxy/jenkins/${BASE}/test
(assuming your Jenkins is located at http://your.reverse.proxy/jenkins/ - and is open to anonymous read access)