|
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 Apache, 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. Make sure that you change the Jenkins httpListenAddress from its default of 0.0.0.0 to 127.0.0.1 or any Apache-level restrictions can be easily bypassed by hitting the Jenkins port directly. mod_proxymod_proxy works by making Apache perform "reverse proxy" — when a request arrives for certain URLs, Apache becomes a proxy and further forward that request to Jenkins, then it forwards the response back to the client. The following Apache modules must be installed : a2enmod proxy a2enmod proxy_http A typical set up for mod_proxy would look like this: ProxyPass /jenkins http://localhost:8081/jenkins nocanon ProxyPassReverse /jenkins http://localhost:8081/jenkins ProxyRequests Off AllowEncodedSlashes NoDecode # Local reverse proxy authorization override # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu) <Proxy http://localhost:8081/jenkins*> Order deny,allow Allow from all </Proxy> This assumes that you run Jenkins on port 8081.
The ProxyRequests Off prevents Apache from functioning as a forward proxy server (except for ProxyPass), it is advised to include it unless the server should function as a proxy.
mod_proxy with HTTPSIf you'd like to run Jenkins with reverse proxy in HTTPS, one user reported that HTTPS needs to be terminated at Jenkins, not at the front-end Apache. See this e-mail thread for more discussion. Alternatively, you can add an additional ProxyPassReverse directive to redirect non-SSL URLs generated by Jenkins to the SSL side. Assuming that your webserver is your.host.com, placing the following within the SSL virtual host definition will do the trick: ProxyRequests Off ProxyPreserveHost On AllowEncodedSlashes NoDecode <Proxy http://localhost:8081/jenkins*> Order deny,allow Allow from all </Proxy> ProxyPass /jenkins http://localhost:8081/jenkins nocanon ProxyPassReverse /jenkins http://localhost:8081/jenkins ProxyPassReverse /jenkins http://your.host.com/jenkins Yet another option is to rewrite the Location headers that contain non-ssl URL's generated by Jenkins. If you want to access Jenkins from https://www.example.com/jenkins, placing the following within the SSL virtual host definition also works: ProxyRequests Off ProxyPreserveHost On ProxyPass /jenkins/ http://localhost:8081/jenkins/ nocanon AllowEncodedSlashes NoDecode <Location /jenkins/> ProxyPassReverse / Order deny,allow Allow from all </Location> Header edit Location ^http://www.example.com/jenkins/ https://www.example.com/jenkins/ But it may also work fine to just use simple forwarding as above (the first HTTPS snippet), and add RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" in the HTTPS site configuration, as the Docker demo (below) does. (X-Forwarded-Port is not interpreted by Jenkins prior to issue #23294 so it may also be desirable to configure the servlet container to specify the originating port.) The collection of snippets above simply don't work out of the box (July 2014), here is a full Apache-oriented "sites-enabled" file (ex: "sites-enabled/example") for a dedicated Jenkins host, combining the ideas from snippets #1 and #3. This was formulated on the TurnKeyLinux Jenkins appliance (v 13.0), after having updated Jenkins to "1.572". TODO (if anyone understands how to do so): Define a more selective path for the <Proxy *> tag, instead of *; I currently have the impression that the <Proxy> section is not even needed. NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerAdmin webmaster@localhost
Redirect permanent / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
ServerAdmin webmaster@localhost
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ nocanon
ProxyPassReverse / http://localhost:8080/
ProxyPassReverse / http://www.example.com/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
mod_ajp/mod_proxy_ajpMore info welcome. Probably we should move the contents from here I wanted to have Jenkins running in a different workspace than my normal Tomcat server, but both available via the Apache web server. So, first up, modify Jenkins to use a different web and ajp port than Tomcat:
HTTP_PORT=9080 AJP_PORT=9009 ... nohup java -jar "$WAR" --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT --prefix=/jenkins >> "$LOG" 2>&1 & Then setup Apache so that it knows that the prefix /jenkins is being served by AJP in the httpd.conf file: LoadModule jk_module libexec/httpd/mod_jk.so AddModule mod_jk.c #== AJP hooks == JkWorkersFile /etc/httpd/workers.properties JkLogFile /private/var/log/httpd/mod_jk.log JkLogLevel info JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories JkRequestLogFormat "%w %V %T" # Here are 3 sample applications - 2 that are being served by Tomcat, and Jenkins JkMount /friki/* worker1 JkMount /pebble/* worker1 JkMount /jenkins/* worker2 Then finally the workers.conf file specified above, that just tells AJP which port to use for which web application: # Define 2 real workers using ajp13 worker.list=worker1,worker2 # Set properties for worker1 (ajp13) worker.worker1.type=ajp13 worker.worker1.host=localhost worker.worker1.port=8009 worker.worker1.lbfactor=50 worker.worker1.cachesize=10 worker.worker1.cache_timeout=600 worker.worker1.socket_keepalive=1 # Set properties for worker2 (ajp13) worker.worker2.type=ajp13 worker.worker2.host=localhost worker.worker2.port=9009 worker.worker2.lbfactor=50 worker.worker2.cachesize=10 worker.worker2.cache_timeout=600 worker.worker2.socket_keepalive=1 worker.worker2.recycle_timeout=300 mod_proxy_ajp+SSLAJP is an arguably cleaner alternative for an SSL-enabled reverse proxy, since Jenkins will get all pertinent HTTP headers untouched. Configuration is a snap too, in three simple steps: 1. Configure an AJP port for Jenkins (as mentioned above) HTTP_PORT=-1 AJP_PORT=9009 ... nohup java -jar "$WAR" --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT --prefix=/jenkins >> "$LOG" 2>&1 & 2. Enable mod_proxy_ajp in Apache: # a2enmod proxy_ajp 3. Include the following snippet in your SSL-enabled VirtualHost: <VirtualHost *:443> ... SSLEngine on ... AllowEncodedSlashes NoDecode ProxyRequests Off ProxyPass /jenkins ajp://localhost:9009/jenkins nocanon </VirtualHost>
mod_rewriteSome people attempted to use mod_rewrite to do this, but this will never work if you do not add a ProxyPassReverse. The following Apache modules must be installed : a2enmod rewrite a2enmod proxy a2enmod proxy_http A typical set up for mod_rewrite would look like this: # Use last flag because no more rewrite can be applied after proxy pass RewriteRule ^/jenkins(.*)$ http://localhost:8081/jenkins$1 [P,L] ProxyPassReverse /jenkins http://localhost:8081/jenkins ProxyRequests Off # Local reverse proxy authorization override # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu) <Proxy http://localhost:8081/jenkins*> Order deny,allow Allow from all </Proxy> This assumes that you run Jenkins on port 8081. For this set up to work, the context path of Jenkins must be the same between your Apache and Jenkins (that is, you can't run Jenkins on http://localhost:8081/ci and have it exposed at http://localhost:80/jenkins) The ProxyRequests Off prevents Apache from functioning as a forward proxy server (except for ProxyPass), it is advised to include it unless the server should function as a proxy. Testing compatibility from pluginsTry https://index.docker.io/u/jglick/jenkins-demo-reverse-proxy/ to see if your plugin works behind an Apache reverse proxy. |
Running Jenkins behind Apache
Skip to end of metadata
Go to start of metadata
Comments (13)
Feb 15, 2011
Ismael Angelo Jr. Casimpan says:
May I know if anyone has succesfully deplyed jenkins using an apache worker mpm ...May I know if anyone has succesfully deplyed jenkins using an apache worker mpm as compared to the default pre-fork?
Thanks in advance,
Ismael
Aug 24, 2011
Granville Raper says:
For those that want to have the Jenkins app as a root app but don't want it in t...For those that want to have the Jenkins app as a root app but don't want it in the root folder, you can use a virtual host in Tomcat to do that so that you're using a single instance of Tomcat instead of multiple instances
In the server.xml file for Tomcat, nest a new Host element inside of the Engine element. You can place it before or after the default Host element. Inside the new host create a new Context element and an Alias element. If Jenkins.war is in the webaps folder and it's been deployed so that you have webapps/jenkins with all the goodies inside then the following will work.
You can now add jenkins.example.com to your DNS and hit that hostname with whatever port the connector is setup on. I used a DNS trick of putting "127.0.0.1 jenkins" in my hosts file so that the server would be able to respond to http://jenkins:8080/ which allowed me to test it. The Alias element will also work, but I would recommend setting that up with a real dns server. The <Host name=""> could also be "jenkins.example.com" and you could do without the Alias if you prefer.
Once I had that working, I was able to setup Apache like stated above with the ProxyPass and ProxyPassReverse statements being changed to ProxyPass / http://jenkins:8080/. Notice that I'm using the same port as localhost for Tomcat default, not a new one. if you wanted a new port, you can obviously get that setup as well.
Jun 22, 2012
Jaime Gago says:
For those out there trying to set the context path on RHEL/CentOS/SL 6 with a cl...For those out there trying to set the context path on RHEL/CentOS/SL 6 with a classic install with yum from official repository, you will find the JENKINS_ARGS flag in /etc/sysconfig/jenkins.
Aug 29, 2012
Jesse Bowes says:
When I follow the mod_proxy instructions, it works but 'Â' characters are t...When I follow the mod_proxy instructions, it works but 'Â' characters are thrown in before almost every link on the page.
Sep 28, 2012
Emil Petkov says:
Hello, I followed the instructions and the reverse proxy with Apache in front o...Hello,
I followed the instructions and the reverse proxy with Apache in front of Jenkins does not work. I have set up an Apache virtualhost config that proxies to Jenkins:
# Apache virtualhost
<VirtualHost *:8084>
ServerAdmin emil@my_email.com
ProxyRequests Off
ProxyPass /jenkins http://localhost:8084/jenkins
ProxyPassReverse /jenkins http://localhost:8084/jenkins
<Proxy http://localhost:8084/jenkins*>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost on
</VirtualHost>
The virtualhost is activated, no errors.
You can see my changes to /etc/default/jenkins here:
...
HTTP_PORT=8084
PREFIX=/jenkins
...
JENKINS_ARGS="--httpListenAddress=127.0.0.1 --webroot=/var/cache/jenkins/war --prefix=$PREFIX --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT"
I am tailing the apache logs and jenkins, but when I try to access http://10.100.25.14:8084/jenkins, I get nothing, no page. When I start Jenkins without --httpListenAddress=127.0.0.1, I open http://10.100.25.14:8084/jenkins successfully, but this is directly accessing Jenkins, does not pass through Apache.
Any ideas what might be the problem in my reverse proxy config? It is pretty standard.
Thanks,
Emil
Apr 15, 2014
John Heller says:
RHEL/CentoOS 6 uses Apache 2.2.15 and the NoDecode option for AllowEncodedS...RHEL/CentoOS 6 uses Apache 2.2.15 and the NoDecode option for AllowEncodedSlashes only became available in 2.2.18. Can you recommend settings suitable for RHEL/CentOS.
May 05, 2014
svollmer - says:
Same problem here with Ubuntu 10.04 LTS which uses Apache 2.2.14.Same problem here with Ubuntu 10.04 LTS which uses Apache 2.2.14.
Jun 25, 2014
Billy Foss says:
FYI, I found that using AllowEncodedSlashes On worked in our configuration -...FYI,
I found that using
AllowEncodedSlashes On
worked in our configuration
- Jenkins LTS 1.554.2
- RedHatEnterpriseServer-6.5
FYI,
I found that using
AllowEncodedSlashes On
worked in our configuration
- Jenkins LTS 1.554.2
- RedHatEnterpriseServer-6.5
May 02, 2014
Dimitris Stafylarakis says:
Hi, I'm no expert when it comes to Apache & proxies etc but I may have a use...Hi, I'm no expert when it comes to Apache & proxies etc but I may have a useful tip.
I didn't use the nocanon option at ProxyPass (less secure according to the documentation). Instead, I used a rewrite rule with the NE flag enabled, as follows:
RewriteEngine on RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f RewriteRule .* http://127.0.0.1:8080%{REQUEST_URI} [NE,P,QSA]Hope it helps somebody.
May 05, 2014
Gene Ratzlaff says:
I followed the "mod_proxy_ajp+SSL" section, steps 1&3 on RHEL 6.5 with...I followed the "mod_proxy_ajp+SSL" section, steps 1&3 on RHEL 6.5 with tomcat6 and it seems to be working fine:
Step1: I installed jenkins with yum, and am starting jenkins with "service jenkins start", not the "nohup..." Modify /etc/sysconfig/jenkins with
JENKINS_PORT=-1
JENKINS_AJP_PORT=9009
JENKINS_ARGS="--prefix=/jenkins"
JENKINS_LISTEN_ADDRESS=127.0.0.1
Step 2: a2enmod isn't RHEL, but this was already enabled by default.
Step 3: used 'AllowEncodedSlashes On')
Don't forget to enable SSL in iptables (port 443).
May 05, 2014
Gene Ratzlaff says:
Oh, wait. I had not switched to httpListenAddress=127.0.0.1. It stopped working ...Oh, wait. I had not switched to httpListenAddress=127.0.0.1. It stopped working when I did. Back to the drawing boards...
May 05, 2014
Gene Ratzlaff says:
OK, my ssl.conf mods were not preceded by 'NameVirtualHost *:443" as in: ...OK, my ssl.conf mods were not preceded by 'NameVirtualHost *:443" as in:
May 06, 2014
Terence Miller says:
Please add example howto connect slaves via jnlp (connetion on special static tc...Please add example howto connect slaves via jnlp (connetion on special static tcp port after init via http is needed) to jenkins at Backend Zone through a Frontend DMZ (apache) Server . It would be useful for enterprise environment to have http protocol/ports usage only. See https://issues.jenkins-ci.org/browse/JENKINS-22877
Add Comment