4

I'm using Docker Compose to host a small dev environment, which includes a DNS container. I've added the docker-machine's IP as the first DNS server in my wifi settings (there are no wired connections):

wifi DNS settings

192.168.99.100 is the docker-machine's IP address. I also flushed the DNS/mDNSResponder cache with the command sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder.

All command line utilities to resolve hostnames resolve the hostname properly, including nslookup, dig, and host:

$ nslookup
> foo.foobar
Server:     192.168.99.100
Address:    192.168.99.100#53

Non-authoritative answer:
Name:   foo.foobar
Address: 172.21.0.5
> exit

$ dig foo.foobar

; <<>> DiG 9.8.3-P1 <<>> foo.foobar
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12335
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;foo.foobar.            IN  A

;; ANSWER SECTION:
foo.foobar.     17  IN  A   172.21.0.5

;; Query time: 4 msec
;; SERVER: 192.168.99.100#53(192.168.99.100)
;; WHEN: Mon Jun  6 07:49:50 2016
;; MSG SIZE  rcvd: 44

$ host foo.foobar
foo.foobar has address 172.21.0.5
Host foo.foobar not found: 3(NXDOMAIN)

The only suspicious thing in the above output is the last line. When I curl or wget by name, I get failure:

$ curl http://foo.foobar
curl: (6) Could not resolve host: foo.foobar
$ wget http://foo.foobar
--2016-06-06 08:27:05--  http://foo.foobar/
Resolving foo.foobar... failed: nodename nor servname provided, or not known.
wget: unable to resolve host address 'foo.foobar'

Using the IP address works, confirming my routes are set up properly:

$ curl http://172.21.0.5
Hello foo
$ wget http://172.21.0.5
--2016-06-06 08:28:22--  http://172.21.0.5/
Connecting to 172.21.0.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9 [text/html]
Saving to: 'index.html'

index.html                   100%[==============================================>]       9  --.-KB/s    in 0s

2016-06-06 08:28:22 (732 KB/s) - 'index.html' saved [9/9]

Lastly, when I use Chrome or Safari to fetch http://foo.foobar, I get DNS failures (and getting by IP works fine).

There seem to me many posts on this out on the interwebs, but none of them seem to work for me.

What's the secret sauce to get El Capitan to resolve the hostname foo.foobar properly?

Edit: add proxies screenshot:

Proxies

Edit 2: add docker version output:

$ docker --version
Docker version 1.11.0, build 4dc5990
$ docker-compose --version
docker-compose version 1.7.0, build 0d7bf73
$ docker-machine --version
docker-machine version 0.7.0, build a650a40

Edit 3: add docker files

NB: I've redacted the sensitive stuff.

Here's the script we use to fire everything up and exec commands in the app's container; it is meant to be run from a node.js application's root directory (containing file package.json) on the host machine (mapped to /app in the app container) whose basename also serves as the application name, and it assumes docker-machine start default has been already successfully run:

#!/usr/bin/env bash

if [ ! -f ~/.npmrc ]; then
  touch ~/.npmrc
fi
if [ "$(uname)" == "Darwin" ]; then
  eval $(docker-machine env default)
fi

if [ -z "$APP_NAME" ]; then
  APP_NAME=${PWD##*/} # (basename of the current directory)
fi

if [ -d .git ]; then
  APP_TAG=$(git status | head -n 1 | awk '{ print $3 }')
else
  APP_TAG=master
fi

docker-compose up -d

if [ "$#" -eq 0 ]; then
  CMD=bash
else
  CMD="$@"
fi

docker exec -it ${APP_NAME}-app $CMD

Here's our app's Dockerfile (found at ./docker/Dockerfile, where . is the node.js application's root directory):

FROM node:4

# essential invariants
ENV PATH ./node_modules/.bin:$PATH
RUN apt-get update && \
     apt-get install -y openjdk-7-jre-headless # (we need java7)
RUN apt-get install -y sudo

# app & user specifics
ARG UID
ARG USER
RUN useradd -ms /bin/bash ${USER:-docker} --uid ${UID:-1000}
RUN adduser ${USER:-docker} sudo
RUN echo "${USER:-docker} ALL=(ALL) NOPASSWD: ALL"  >> /etc/sudoers
USER ${USER:-docker}

COPY .setup.sh /.setup.sh
CMD ["/.setup.sh"]

Here's the file .setup.sh, found next to and referred to by the Dockerfile above; it works around file permissions issues with volumes shared from the host machine:

#!/usr/bin/env bash

# Ensures current user is the owner of /app's files
UID=$(id -u)
FILE_OWNER_UID=$(stat -c '%u' /app/package.json)
USER=$(id -un)
if [ ! $UID == $FILE_OWNER_UID ]; then
  echo "Changing ${USER}'s uid from $UID to $FILE_OWNER_UID"
  sudo usermod -u $FILE_OWNER_UID $USER
fi

# Keeps container running
sleep infinity

Here is our docker-compose.yaml:

version: '2'
services:
  app:
    build:
      context: ./docker
      args:
        USER: docker
    image: ${APP_NAME}:${APP_TAG}
    environment:
      FORCE_AMQP: 1
      AMQP_HOST: ${APP_NAME}-amqp
      PORT: 80
      MONGO_HOST: ${APP_NAME}-mongo
    depends_on:
      - amqp
      - mongo
    hostname: ${APP_NAME}-app
    container_name: ${APP_NAME}-app
    volumes:
      - ./:/app
      - ~/.npmrc:/home/docker/.npmrc
      - ~/.npm:/home/docker/.npm
    networks:
      network:
        aliases:
          - ${APP_NAME}.foobar
    working_dir: /app
  amqp:
    hostname: ${APP_NAME}-amqp
    container_name: ${APP_NAME}-amqp
    image: rabbitmq
    networks:
      - network
  mongo:
    hostname: ${APP_NAME}-mongo
    container_name: ${APP_NAME}-mongo
    image: mongo:3.0.4
    networks:
      - network
  dns:
    hostname: ${APP_NAME}-dns
    container_name: ${APP_NAME}-dns
    image: andyshinn/dnsmasq
    cap_add:
      - NET_ADMIN
    ports:
      - 53:53/udp
      - 53:53/tcp
    command: --max-cache-ttl=30 --max-ttl=30
    networks:
      - network
networks:
  network:
    driver: bridge

Here is how we add a route to the docker-machine's network for Mac OS X machines that use docker-machine via VirtualBox (not dlite):

#!/usr/bin/env bash

eval $(docker-machine env default)
DOCKER_IP=$(docker-machine ip default)

sudo route -n add $(docker network inspect --format '{{ range .IPAM.Config }}{{ .Subnet}}{{end}}' ${PWD##*/}_network) $DOCKER_IP
  • What does it say in your proxies configuration? – Allan Jun 6 '16 at 13:58
  • @Allan, I added a screenshot of the proxies configuration to the original question. – Matthew Adams Jun 6 '16 at 14:01
  • Can you ping foo.foobar? – Allan Jun 6 '16 at 14:06
  • @Allan, no: $ ping foo.foobar ping: cannot resolve foo.foobar: Unknown host – Matthew Adams Jun 6 '16 at 14:07
  • @klanomath, one of the containers we're spinning up using Docker Compose uses Docker image andyshinn/dnsmasq, so neither the embedded one or the container DNS for the default bridge. I admit to being a Docker noob, so maybe I'm missing something. The puzzling thing is that nslookup, dig & host all perform successful name resolution at the command line, but curl & ping fail. I've concluded that they are using different mechanisms for name resolution than what I've configured. I'll also add docker version output to the OP. – Matthew Adams Jun 7 '16 at 13:38

You must log in to answer this question.

Browse other questions tagged .