PostgreSQL客户端无法解析Docker容器中的主机名

时间:2017-12-29 04:27:57

标签: postgresql docker docker-compose

我尝试使用Docker Compose创建两个容器:一个包含PostgreSQL(实际上是PostGIS),另一个包含一个查询PostgreSQL的Web应用程序。

我的docker-compose.yaml是:

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

应用程序Dockerfile是:

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

PostgreSQL Dockerfile只是:

FROM mdillon/postgis

PostgreSQL容器启动并且似乎完美运行 - 我可以从主机查询它,只要我使用PostgreSQL容器的IP地址,我就可以从应用程序容器中查询它。

然而,' psql'在app容器中运行无法访问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

通常,' psql'在无法解析给定的主机名时输出此诊断信息。但是,主机名解析似乎在应用程序容器中正常工作:

$ 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# 

此外,PostgreSQL客户端和服务器似乎与此主机名相关的问题完全兼容:

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# 

为什么没有&#39; psql&#39;解决&#39; db&#39;到172.22.0.2,作为&#39;挖掘&#39;是能够做到的,因而有效吗?

1 个答案:

答案 0 :(得分:1)

我正在设置PGHOSTADDR,它需要是一个点分十进制IP地址,而我应该设置PGHOST,它可以是一个主机名,如the PostgreSQL documentation中明确解释的那样。

取消设置PGHOSTADDR而不是设置PGHOST使'psql'按预期工作:

root@3a11fb7a22a1:/var/www/html# psql -U postgres -c 'SELECT 1;'
psql: could not translate host name "db" to address: Name or service not known
root@3a11fb7a22a1:/var/www/html# unset PGHOSTADDR
root@3a11fb7a22a1:/var/www/html# PGHOST=db
root@3a11fb7a22a1:/var/www/html# export PGHOST
root@3a11fb7a22a1:/var/www/html# psql -U postgres -c 'SELECT 1;'
 ?column? 
----------
        1
(1 row)

root@3a11fb7a22a1:/var/www/html# 

RTFM的另一个失败。