I have a Linux server running Jenkins (HTTP on port 8080) and the same server is also running Docker 1.12.1. I used some iptables rules (as per official Jenkins install docs) to redirect port 8080 to the host's port 80, so that default HTTP would work for Jenkins (i.e. http://myserver
rather than http://myserver:8080
):
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
However these rules break Docker's ability to download the correct resources via HTTP during a docker build
command. For instance, RUN apt-get update
fails with multiple "failed to download" errors. Doing wget http://www.google.com
inside the container returns the HTML for the Jenkins main page. HTTP GETs from the host work fine. Removing the iptables rules results in RUN apt-get update
working again. So I think those iptables rules are interfering with docker's network mechanism.
Can such a port redirection coexist with Docker? If so, how would one go about writing iptables rules to solve this problem?
A possible modification to the iptables rules is to remove both and replace with:
This will ensure that, for my case, only TCP traffic on port 80 through interface
eth0
will be redirected. Traffic originating from a docker container on the host will not be redirected. Note that I've left out the localhost redirection too, although presumably that could be modified to avoid filtering anything originating from interfacedocker0
.Another solution is to employ a reverse proxy to forward incoming HTTP requests on TCP port 80 to the host's port 8080. I used Caddy with the following simple Caddyfile:
With this in place, I can remove the iptables rules entirely.
This seems to provide a simple redirection on port 80, as well as allowing docker containers to use outgoing HTTP normally.