2

I have custom java application that downloads files from web using org.​apache.​commons.​io.FileUtils.copyFile(File srcFile, File destFile). It works perfectly when it runs directly but when I run it from a docker container I get following exception:

Exception in thread "main" java.net.UnknownHostException: <MY HOST>
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at org.apache.commons.io.FileUtils.copyURLToFile(FileUtils.java:1506)

I tried exposing http and https ports on the container with EXPOSE 8080, EXPOSE 8443 and running with -P option. Next thing was running the container with --hostname=127.0.0.1 option. Then I found a hack for Dockerfile: RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf. Nothing helped. Do you have any suggestions how to solve this?

Docker version 17.10.0-ce, build f4ffd25, Dockerfile base image: openjdk:8

Docker image /etc/hosts contains:

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      afa4800849e0
mohan08p
  • 5,002
  • 1
  • 28
  • 36
Abdul
  • 537
  • 1
  • 5
  • 21
  • 1
    Is the host you're quering a public host? Or is it setup in the hosts file of your machine? Or may be is it setup via some internal DNS server? Try to ssh into the container and ping the host by dns name and by ip. – Sasha Shpota Jan 10 '18 at 10:46
  • What is ? can it be resolved via public DNS? – Henry Jan 10 '18 at 10:48
  • is a placeholder that I added to log only (correct host is used in app), and the host is public – Abdul Jan 10 '18 at 10:51
  • @OleksandrShpota The host is public. I can ping the host from the container by IP but not by hostname. So DNS problem? – Abdul Jan 10 '18 at 10:56
  • It looks like that. Try to ssh into the container and check what DNS server is used. You can do it via `cat /etc/resolv.conf`. And then if the DNS is incorrect, or it doesn't hold the host - try to start the container providing custom DNS: `--dns=IP_ADDRESS` (probably Google DNS would be ok). Or as a workaround you can add the host into the containers `/etc/hosts` - that will solve the problem for sure. See also https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/. – Sasha Shpota Jan 10 '18 at 11:09
  • @OleksandrShpota I got `nameserver 10.0.2.3`. When I used `--dns=8.8.8.8` it worked. Can you post an answer so I can accept? Thanks – Abdul Jan 10 '18 at 11:26

1 Answers1

4

The problem is in the DNS server used inside the container. It either doesn't match with the hosts DNS or it doesn't hold the requested DNS name.

You can solve the issue by passing a well known DNS server during container startup.

Use

--dns=8.8.8.8

to refer to Google DNS.

See also the docker documentation for DNS setup.

Sasha Shpota
  • 9,436
  • 14
  • 75
  • 148