DEV Community

David Ojeda
David Ojeda

Posted on • Edited on • Originally published at blog.davidojeda.dev

Make Requests from Docker Container Running on Jenkins

This post is about a specific problem I encountered where I couldn't make any requests from my Docker container to the outside world. It was my first time working with Jenkins Pipelines and decided to use Docker as my isolation agent.

Some facts related to my environment:

  • Jenkins is running on Tomcat, not on a Docker container
  • I have port redirection (80 to 8080 and 443 to 8443) using iptables

Code in question

The relevant part of my Jenkinsfile is this:

stage('build and test apps') { failFast true parallel { stage('front end') { steps { sh 'npm install --prefix front_end/' sh 'npm run build --prefix front_end/' sh 'npm run test --prefix front_end/' } } stage('back end') { steps { sh 'npm install --prefix back_end/' sh 'npm run test --prefix back_end/' } } } } 
Enter fullscreen mode Exit fullscreen mode

The logs

The requests needed on the npm install command were failing with 403 http errors and this log was appearing:

npm ERR! Unexpected token < in JSON at position 0 npm ERR! <html><head><meta http-equiv='refresh' content='1;url=/login?from=%2Freact-scripts'/><script>window.location.replace('/login?from=%2Freact-scripts');</script></head><body style='background-color:white; color:white;'> npm ERR! npm ERR! npm ERR! Authentication required npm ERR! <!-- npm ERR! You are authenticated as: anonymous npm ERR! Groups that you are in: npm ERR! npm ERR! Permission you need to have (but didn't): hudson.model.Hudson.Read npm ERR! ... which is implied by: hudson.security.Permission.GenericRead npm ERR! ... which is implied by: hudson.model.Hudson.Administer npm ERR! --> npm ERR! npm ERR! </body></html> npm ERR! npm ERR! If you need help, you may report this error at: npm ERR! <https://github.com/npm/npm/issues> 
Enter fullscreen mode Exit fullscreen mode

After reading the logs, the first thing I thought was: this is something related to permissions of the user running the Docker container- tomcat in my case -but they weren't.

After debugging for quite a while, I stumbled upon some divine light on StackOverflow. Thanks to this, I found that I was redirecting all port 80 and 443 trafic from everywhere to their corresponding 8080 and 8443 ports.

The solution

Alter the iptables to create a negated rule and avoid redirects from the Docker subnet.

First, check your current iptables with this command:

iptables -t nat -L -n --line-numbers

Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 8080 2 REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 redir ports 8443 3 tcp -- 0.0.0.0/0 0.0.0.0/0 4 DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination 1 REDIRECT tcp -- 0.0.0.0/0 127.0.0.1 tcp dpt:443 redir ports 8443 2 REDIRECT tcp -- 0.0.0.0/0 127.0.0.1 tcp dpt:80 redir ports 8080 3 DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 1 MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 Chain DOCKER (2 references) num target prot opt source destination 1 RETURN all -- 0.0.0.0/0 0.0.0.0/0 
Enter fullscreen mode Exit fullscreen mode

The value 0.0.0.0/0 on the source column refers to all trafic. So, in my case, I need to replace the first two entries of both the PREROUTING and OUTPUT chain:

Note: The default Docker subnet is 172.17.0.0/16. If you changed the default configurations make sure to change them in the commands also.

PREROUTING

iptables -t nat -R PREROUTING 1 ! -s 172.17.0.0/16 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 
Enter fullscreen mode Exit fullscreen mode
iptables -t nat -R PREROUTING 2 ! -s 172.17.0.0/16 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443 
Enter fullscreen mode Exit fullscreen mode

OUTPUT

iptables -t nat -R OUTPUT 1 ! -s 172.17.0.0/16 -d 127.0.0.1/32 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443 
Enter fullscreen mode Exit fullscreen mode
iptables -t nat -R OUTPUT 2 ! -s 172.17.0.0/16 -d 127.0.0.1/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 
Enter fullscreen mode Exit fullscreen mode

Now, requests from the Docker container return with a 200 http status and everyone is happy ๐Ÿค— Hope this helps you if you are having a similar problem!

As a side note, while doing all this, I also needed to learn more about iptables and their different options. I found this quick guide from linode handy.

Thanks for reading me!

Top comments (0)