I'm trying to use Docker Compose to create two containers: one containing PostgreSQL (actually PostGIS), and the other containing a web app that queries PostgreSQL.
My docker-compose.yaml is:
version: '3.1'
services:
db:
build:
context: .
dockerfile: Dockerfile-db
restart: always
ports:
- 5432:5432
web:
build:
context: .
dockerfile: Dockerfile-web
args:
PGHOSTADDR: db
restart: always
ports:
- 80:80
depends_on:
- db
The application Dockerfile is:
FROM php:apache
ARG PGHOSTADDR
ENV PGHOSTADDR=$PGHOSTADDR
COPY . /var/www/html/
RUN apt-get update && mkdir -p /usr/share/man/man1 /usr/share/man/man7 && apt-get install -y postgresql-client strace ltrace iputils-ping bind9-host dnsutils
CMD until psql -c '\q' ; do sleep 1 ; done ; /usr/sbin/apache2
The PostgreSQL Dockerfile is just:
FROM mdillon/postgis
The PostgreSQL container starts and appears to work perfectly - I can query it from the host, and I can query it from the application container so long as I use the IP address of the PostgreSQL container.
However, 'psql' running in the app container is unable to reach PostgreSQL:
$ docker-compose up -d && echo MARK && docker-compose logs --follow web
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Starting myapp_db_1 ...
Starting myapp_db_1 ... done
Starting myapp_web_1 ...
Starting myapp_web_1 ... done
MARK
Attaching to myapp_web_1
web_1 | psql: could not translate host name "db" to address: Name or service not known
web_1 | psql: could not translate host name "db" to address: Name or service not known
web_1 | psql: could not translate host name "db" to address: Name or service not known
web_1 | psql: could not translate host name "db" to address: Name or service not known
Usually, 'psql' outputs this diagnostic when it fails to resolve the hostname given. However hostname resolution seems to be working fine in the app container:
$ docker exec -it myapp_web_1 bash
root@3a11fb7a22a1:/var/www/html# dig db
; <<>> DiG 9.10.3-P4-Debian <<>> db
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21082
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;db. IN A
;; ANSWER SECTION:
db. 600 IN A 172.22.0.2
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Fri Dec 29 04:18:32 UTC 2017
;; MSG SIZE rcvd: 38
root@3a11fb7a22a1:/var/www/html# ping -c 2 db
PING db (172.22.0.2) 56(84) bytes of data.
64 bytes from myapp_db_1.myapp_default (172.22.0.2): icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from myapp_db_1.myapp_default (172.22.0.2): icmp_seq=2 ttl=64 time=0.045 ms
--- db ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1020ms
rtt min/avg/max/mdev = 0.036/0.040/0.045/0.007 ms
root@3a11fb7a22a1:/var/www/html#
Also, the PostgreSQL client and server appear to be working perfectly apart from this hostname-related problem:
root@3a11fb7a22a1:/var/www/html# unset PGHOSTADDR
root@3a11fb7a22a1:/var/www/html# psql -h 172.22.0.2 -U postgres -c 'SELECT 1;'
?column?
----------
1
(1 row)
root@3a11fb7a22a1:/var/www/html#
Why isn't 'psql' resolving 'db' to 172.22.0.2, as 'dig' is able to do, and hence working?