50

I'm running Ubuntu 11.10 and have run sudo apt-get install jenkins to install Jenkins on this system.

I've seen some tutorials on how to setup a reverse proxy (Apache, Nginx, etc), however this is a VM dedicated for just jenkins and I'd like keep it as lean as possible while having jenkins running on port 80.

I've found the upstart config in /etc/init/jenkins.conf and modified the port to 80 env HTTP_PORT=80

When I start jenkins via service jenkins start, ps reveals that it runs for a few seconds then terminates.

Is this because jenkins is running as the jenkins user on a privileged port? If so, how do I fix this? Any other ideas a welcome.

Here is the upstart config:

description "jenkins: Jenkins Continuous Integration Server"
author "James Page <james.page@ubuntu.com>"

start on (local-filesystems and net-device-up IFACE!=lo)
stop on runlevel [!2345]

env USER="jenkins"
env GROUP="jenkins"
env JENKINS_LOG="/var/log/jenkins"
env JENKINS_ROOT="/usr/share/jenkins"
env JENKINS_HOME="/var/lib/jenkins"
env JENKINS_RUN="/var/run/jenkins"
env HTTP_PORT=80
env AJP_PORT=-1
env JAVA_OPTS=""
env JAVA_HOME="/usr/lib/jvm/default-java"

limit nofile 8192 8192

pre-start script
    test -f $JENKINS_ROOT/jenkins.war || { stop ; exit 0; }
    $JENKINS_ROOT/bin/maintain-plugins.sh   
    mkdir $JENKINS_RUN > /dev/null 2>&1  || true
    chown -R $USER:$GROUP $JENKINS_RUN || true
end script

script
    JENKINS_ARGS="--webroot=$JENKINS_RUN/war --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT"
    exec daemon --name=jenkins --inherit --output=$JENKINS_LOG/jenkins.log --user=$USER \
        -- $JAVA_HOME/bin/java $JAVA_OPTS -jar $JENKINS_ROOT/jenkins.war $JENKINS_ARGS \
        --preferredClassLoader=java.net.URLClassLoader
end script
hafichuk
  • 8,680
  • 9
  • 32
  • 52

13 Answers13

47

Another solution is to simply use iptables to reroute incoming traffic from 80 to 8080. The rules would look like:

-A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
-A INPUT -i eth0 -p tcp --dport 8080 -j ACCEPT
-A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

Reformatted as an iptables.rules file:

*filter
:INPUT ACCEPT [100:100000]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [95:9000]
-A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
-A INPUT -i eth0 -p tcp --dport 8080 -j ACCEPT
COMMIT

*nat
-A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
COMMIT

The advantage of a iptable.rules file is the rules can persist after reboots. Just make sure to integrate any other current iptable rules into the same file!

On Redhat/CentOS this file can go in /etc/sysconfig/iptables.

On Debian/Ubuntu systems they can be saved in /etc/iptables/rules.v4 by using the iptables-persistent package. Or the iptable.rules can be called by modifying /etc/network/interfaces or hooking into if-up/if-down scripts. The Ubuntu Community wiki has a great page explaining these methods.

As is usually the case with networking, there's a lot of different ways to accomplish the same result. Use what works best for you!

Chris Laskey
  • 1,634
  • 1
  • 17
  • 14
37
  1. Go to /etc/default folder --> Open the file "jenkins"
  2. Modify the line HTTP_PORT=8080 as HTTP_PORT=80
  3. Start jenkins as root by using the command: sudo /etc/init.d/jenkins start
  4. Open a browser and browse as localhost:80

that's it

bain
  • 1,070
  • 9
  • 10
Ripon Al Wasim
  • 34,088
  • 37
  • 146
  • 165
  • for step #3, what user are you starting it with? – hafichuk Jan 10 '13 at 16:17
  • for step #3: you can start as root. Or, it's not root user use "sudo" as sudo /etc/init.d/jenkins start – Ripon Al Wasim Jan 11 '13 at 03:52
  • I've made the change you mentioned and am getting what seems to be a port 80 error in the jenkins log. The snip is:Caused by: java.io.IOException: Failed to listen on port 80 at winstone.HttpListener.getServerSocket(HttpListener.java:119) at winstone.HttpListener.start(HttpListener.java:72) at winstone.Launcher.spawnListener(Launcher.java:220) ... 8 more Caused by: java.net.BindException: Permission denied – hafichuk Jan 11 '13 at 05:46
  • Is there any other application running on port 80? please check – Ripon Al Wasim Jan 11 '13 at 11:31
  • @hafichuk: Can you please check it by doing change the port as any other value? (e.g. 8888, or 88 etc.) – Ripon Al Wasim Jan 11 '13 at 11:42
  • It ran on 8080 with no problems. – hafichuk Jan 11 '13 at 15:47
  • No other applications are using port 80. – hafichuk Jan 11 '13 at 15:48
  • 6
    I don't really understand why this answer is not upvoted and instead you try to do some weird workarounds. I did exactly as Ripon suggested and works like a charm. Just one line of configuration. hafichuk has problems with 'permission denied' exception probably because he's not runnig jenkins with root privileges! Linux ports <1024 are restricted to be bound by non-root users. – omnomnom Apr 05 '13 at 10:10
  • 12
    Starting a webapplication as root is a terrible idea. It is much better to configure Apache HTTPD or redirect with the iptables trick explained in the other answers. – Sanne Apr 07 '13 at 13:29
  • 2
    Agree that running as root is a bad idea, but I was referring to the particular problem. We can run it as a separate user, chroot it and so forth - Ripon solution would be fine for all these cases. – omnomnom Apr 08 '13 at 10:15
  • 22
    @PiotrekDe the reason it's not upvoted is because it doesn't work. When I change HTTP_PORT to 80 from 8080, Jenkins fails to start. Here's the backtrace I got: https://gist.github.com/tubbo/305164071d00409f6259 – tubbo Oct 14 '13 at 18:55
  • 1
    You just suggest another way of setting up jenkins port. In case jenkins not running as root, it will face the same problem described in question. – artkoshelev Oct 24 '14 at 09:28
  • It will not work if the port you are trying to configure it to is already being used. I tried 8181 and it failed to start. But 9090 worked for me. Also, one may need sudo for Step#3. Thanks – Master.Aurora Apr 14 '15 at 07:37
  • Yes, the port you want to use must free, I mean it should be unused. – Ripon Al Wasim Apr 15 '15 at 04:29
31

Give a try to 'authbind':

sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80 
sudo chown jenkins /etc/authbind/byport/80

Then modify the script above to have (add authbind before the $JAVA_HOME/bin/java part):

exec daemon --name=jenkins --inherit --output=$JENKINS_LOG/jenkins.log \
--user=$USER -- authbind $JAVA_HOME/bin/java $JAVA_OPTS \
-jar $JENKINS_ROOT/jenkins.war $JENKINS_ARGS \
--preferredClassLoader=java.net.URLClassLoader

For newer Jenkins installations (1.598) on newer Ubuntu installations (14.04) edit /etc/init.d/jenkins and add authbind before $JAVA

$SU -l $JENKINS_USER --shell=/bin/bash -c "$DAEMON $DAEMON_ARGS -- authbind $JAVA $JAVA_ARGS -jar $JENKINS_WAR $JENKINS_ARGS" || return 2

As mentioned by Alan (see comment below) if you need IPv6 and your system is lower than Quantal you can instead of using apt-get to install authbind download a higher version. Make sure you have libc6 and libc6-udeb installed. Here is authbind version 2.1.1 from Ubuntu:

Then execute:

sudo dpkg -i authbind_2.1.1_amd64.deb
# or sudo dpkg -i authbind_2.1.1_i386.deb

sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80 
sudo chown jenkins /etc/authbind/byport/80
Community
  • 1
  • 1
JScoobyCed
  • 9,128
  • 4
  • 30
  • 52
  • Thanks! Referencing the [`man page`](http://pwet.fr/man/linux/commandes/authbind) – hafichuk Apr 13 '12 at 17:55
  • 1
    Note to future users of this approach: I'm using Ubuntu 12.04 (Precise) with Jenkins 1.495. The authbind version in Precise is 1.20build3. authbind didn't support ipv6 until 2.0, so I had to use apt pinning to force installation of the authbind version from Quantal (2.1.1). Just FYI in case anyone found this solution but it wasn't working for them. IPv6 may be the problem! – Alan LaMielle Dec 27 '12 at 19:40
  • Thank you. Didn't know about `authbind` before. Still don't know how they do that. Have to read sources. However, it worked. Jenkins now on port 80 :) – hek2mgl Nov 14 '13 at 13:31
  • 1
    This didn't work for me until I upgraded to authbind 2.1.1 as suggested (installed was 1.0). It worked for 'nc -l localhost 80' but failed when running 'java /usr/share/jenkins/jenkins.war --httpPort=80'. Upgrading to 2.1.1 made it all good. Note I wasn't using IPv6 specifically, so it seems it just doesn't work with jenkins before this version. – radman Jan 24 '14 at 04:53
  • One thing to add; I also had to use 'authbind --deep' for it to work. So new version + --deep = jenkins on port 80. – radman Jan 24 '14 at 05:04
  • 1
    I cannot find `authbind` or its equivalent for CentOs. – Anonymous Sep 10 '14 at 04:01
  • could never make this work. authbind 2.1.1, turned off ipv6, passed -Djava.net.preferIPv4Stack=true to java, made sure I could make it work with nc -l 0.0.0 80 etc. - ended up using the iptables portforward below – TTimo Sep 28 '14 at 23:18
7

I'd suggest using apache and mod_proxy. This is what I do, and my vhost config looks kinda like this (I also redirect for SSL but you can omit that):

<VirtualHost *:443>
ServerAdmin webmaster@example.com
ServerName ci.example.com

ProxyRequests Off
<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>
ProxyPreservehost on
ProxyPass / http://localhost:8080/

Header edit Location ^http://ci.example.com/ https://ci.example.com/

SSLEngine on
SSLCertificateFile /etc/apache2/keys/apache.pem
</VirtualHost>
regulatethis
  • 2,232
  • 14
  • 17
  • I tried the authbind method since it looked the most correct, but couldn't get it to work. This is what I ended up having to do (since I didn't want to worry about IP tables). Btw, for some setup info for mod_proxy on Ubuntu, see here: https://abhirama.wordpress.com/2008/11/03/apache-mod_proxy-in-ubuntu/ – Earlz Jan 21 '14 at 15:55
  • Omitting the SSL to `` is also ok, it works for me. – Chetabahana Jan 30 '16 at 15:40
5

You can achieve this using the following methods.

  1. An IP table forwarding rule.
  2. Using a reverse proxy like Nginx.
  3. Running Jenkins behind a load balancer.

Method 1: Running Jenkins On 80 Using IP Table Forwarding Rule

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

Now, you should save these rules so that it will persist even after an IPtable or a system restart.

For Redhat based systems, run the following.

sudo iptables-save > /etc/sysconfig/iptables

For Debian based systems, execute the following command.

sudo sh -c "iptables-save > /etc/iptables.rules"

Now if you access Jenkins on port 80, IP table will automatically forward the requests to 8080.

Method 2: Running Jenkins Behind Nginx Reverse Proxy

Step1: Install Nginx

sudo yum install nginx

Step 2: Open the Nginx configuration file.

sudo vi /etc/nginx/nginx.conf

Step 3: Find the following snippet in the nginx.conf file.

location / {
}

Step 4: Add the following lines between the curly braces.

proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
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;

Step 5: Execute the SELinux command for the Nginx reverse proxy.

sudo setsebool httpd_can_network_connect 1 -P

Step 6: Restart the Nginx server.

sudo systemctl restart nginx

Now if you will be able to access Jenkins on port 80.

Method 3: Jenkins Behind A Load Balancer

Adding a load balancer will add extra cost to the Jenkins setup. If you are on a cloud, you can opt for a cloud-specific load balancer which will send all its port 80 traffic to backend Jenkins 8080 port.

Community
  • 1
  • 1
Subhash
  • 643
  • 6
  • 21
1

Since I used docker. You can use it to run jenkins on port 80, hereafter a snippet of my script:

JENKINS_PORT=80
JENKINS_HOME=/home/jenkins
/usr/bin/docker run -d -p $JENKINS_PORT:8080 -v $JENKINS_HOME jenkins
Ali SAID OMAR
  • 4,760
  • 4
  • 29
  • 53
1

I had the same problem and I found the best solution to it using iptables.

By default Jenkins runs on ports 8080 or 8443. And HTTP/HTTPS servers run on ports 80 and 443.

But this is these are the special ports and the process using them must be owned by root.

But running Jenkins as root is not the best solution(it should be run as its own user) and so does to run Jenkins with a web server such as Apache, and let it proxy requests to Jenkins

The best solution is to use iptables on Linux to forward traffic.

1) Use this command to list the current iptables configuration:

$ iptables -L -n

target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8443
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80

2) If you don't see above entries, then you need to run below commands:

sudo iptables -I INPUT 1 -p tcp --dport 8443 -j ACCEPT

sudo iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT

sudo iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT

sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT

3) Now re-run the $ iptables -L -n command and verify that you are seeing 1st step o/p.

4) The final step is to run the below commands to forward port 80 traffic to 8080, and port 443 traffic to 8443(if you are using HTTPS).

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443

5) Now your URL should stay on port 80

You can find the more details here.

Pratik Patel
  • 1,424
  • 2
  • 16
  • 28
1

Run these lines of code individually:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

If your system is Debian-based, run:

sudo sh -c "iptables-save > /etc/iptables.rules"

If your system is RedHat-based:

sudo iptables-save > /etc/sysconfig/iptables

This process will change your default Jenkins port from 8080 to 80.

Paul Roub
  • 35,100
  • 27
  • 72
  • 83
0

the firewalld way to forward port 8080 to 80:

yum install firewalld
systemctl start firewalld
chkconfig firewalld on
firewall-cmd --permanent --zone=external --change-interface=eth0
firewall-cmd --permanent --zone=external --add-forward-port=port=80:proto=tcp:toport=8080
Greg
  • 9,849
  • 5
  • 26
  • 33
0

None of the answers tells how to simply redirect 80 to 8080 with iptables.
Fortunately, dskrvk's comment does !

There's also a Jenkins wiki documenting this


I just had to copy/paste those lines in my terminal to get the redirect working :

sudo iptables -I INPUT 1 -p tcp --dport 8443 -j ACCEPT
sudo iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT
sudo iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8443

Btw, don't forget to include it to your server's init scripts once tested, or you'll lose the redirect after a reboot. Tested on Debian 8.2 (Jessie)

Balmipour
  • 2,427
  • 20
  • 25
  • You should check out Chris Laskey's answer from a couple years ago. It also shows you how to make the change permanent. – hafichuk Jan 06 '17 at 17:16
  • @hafichuk Yeah, but... I actually didn't want to try thoses for at least two reasons : (1) I didn't really know **where** I should put those (2) I wanted to try the rules before actually putting them in a file. You may tell me I can create a specific file and run it just once in case I screw something, but what I needed was a list of commands making things work, not a file's content to put "somewhere", and run with "some command". Since I'm not familiar with iptables, the "some' I speak of aren't quite clear to me. – Balmipour Jan 14 '17 at 23:56
0

In Ubuntu 16.04, this wiki explains how to do it.

sudo nano /etc/rc.local

Then add the following just before the exit 0

#Requests from outside
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
#Requests from localhost
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

Now reboot or run sudo /etc/rc.local to enable port forwarding

Katu
  • 739
  • 1
  • 17
  • 27
0

changing /etc/default/jenkins doesn't work on my setup ubunutu 16.-4 Jenkins 2.89.4 and the solution to use iptable routes 80 to 8080 whis the opposite of the required result of running jenkins on 80

Barak
  • 11
  • 3
0

Building on other answers in this question: You could use an Nginx side-car container if you're on ECS like I was. A super simple nginx config to the tune of something like

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {

    server {
        listen 80;
        location / {
            proxy_pass http://localhost:8080;
            proxy_redirect off;
            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;
        }
    }
}

should be enough to forward all incoming trafic from port 80->8080. You can then bind this container to port 80, and voila - Jenkins now "resides" on port 80.

Janis Peisenieks
  • 4,740
  • 10
  • 50
  • 82