Forum Bugs

DNS Resolution Differences Between Builds?

pvande-openup
Context:
  • On our team, we run builds of PDFs inside containers running in Docker for Mac.
  • These containers run Alpine Linux 3.13, because they're coupled to our application's needs.
  • Our team has hardware that is a mix of Intel and Apple silicon, so we support both x86_64 and ARM64 platforms in our containers.
  • On our x86_64 machines, we install prince-15-alpine3.13-x86_64.
  • On our ARM64 machines, we install prince-15-linux-generic-aarch64-musl, since there is no Alpine-specific build available.

Issue:
For developer convenience, we run a reverse proxy server locally that dispatches requests to our various containers. Since the majority of browsers will implicitly resolve any domain name ending in .localhost to the loopback address, we are able to avoid running a local nameserver by choosing appropriate hostnames.

Within the containers, we have configured Docker to map those hostnames back to the reverse proxy. In this way, tools running within the container can process HTML markup containing those hostnames. This works fine in all our environments for the majority of our tools.

On our x86 machines, Prince will route a request for http://assets.localhost/some/image.png to the reverse proxy server, as expected.
On our ARM64 machines, Prince will route the same request to 127.0.0.1:80.

Neither behavior is strictly incorrect (according to the relevant specs, user agents may choose to optimize lookups for *.localhost), but it's definitely strange to see the behavior be inconsistent.
wangp
Can you explain how you configure Docker and the containers (the contents of /etc/hosts, /etc/resolv.conf, etc.)? I'm not very familiar Docker.

I assume `curl http://assets.localhost/some/image.png` works for both?
pvande-openup
So sorry to have left your questions hanging for so long.

We configure the containers using Docker Compose's "external links" options, which allow you to specify custom resolutions for hostnames running in the container. In our case, we specify that the `assets.localhost` hostname should resolve to our reverse proxy server container, `nginx-proxy`.

Docker then sets up `/etc/resolv.conf` within the container to point domain name resolution to its internal DNS server.

# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0


That DNS does respond with the expected (read: configured) IP address.

# dig assets.localhost

; <<>> DiG 9.16.33 <<>> assets.localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 281
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;assets.localhost.   IN      A

;; ANSWER SECTION:
assets.localhost. 600 IN     A       172.18.0.2

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Thu May 25 00:10:27 PDT 2023
;; MSG SIZE  rcvd: 88


# dig nginx-proxy

; <<>> DiG 9.16.33 <<>> nginx-proxy
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27239
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;nginx-proxy.                   IN      A

;; ANSWER SECTION:
nginx-proxy.            600     IN      A       172.18.0.2

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Thu May 25 00:10:40 PDT 2023
;; MSG SIZE  rcvd: 56


As you correctly assumed, `curl` does work properly on both platforms, while Prince appears to skip the DNS lookup in the ARM build (implicitly resolving the entire .localhost TLD to 127.0.0.1).

---

In the meantime, we've worked around this by running
socat TCP-LISTEN:80,fork TCP:nginx-proxy:80
in the background to forward local requests to port 80 onward to the reverse proxy. This is functional, but entirely unnecessary on our x86 machines.
wangp
The difference between the two builds is due to a change made in curl 7.85.0, where curl will always resolve *.localhost to 127.0.0.1. See https://github.com/curl/curl/pull/9296

prince-15-alpine3.13-x86_64 uses the system's version of libcurl, which is curl 7.79.1 on Alpine Linux 3.13.

prince-15-linux-generic-aarch64-musl uses its own copy of curl, which is curl 7.86.0.